Bluetooth LE, scanForPeripheralsWithServices in background, increase speed
Asked Answered
M

1

10

I am using Bluetooth LE on iPhone 5S and I have done the following:

  • I have a bluetooth peripheral and I have configured it to advertise each 20th ms on all three bluetooth advertising channels (37, 38 and 39).

  • I have configured my app with UIBacgroundModes = bluetooth-central in Info.plist

  • I have started a scanForPeripheralsWithServices like below

Code:

NSDictionary *options = @{
    CBCentralManagerOptionRestoreIdentifierKey:@"myCentralManagerIdentifier",
    CBCentralManagerScanOptionAllowDuplicatesKey:[NSNumber numberWithBool:YES]
};
self.manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:options];    
[self.manager scanForPeripheralsWithServices:[NSArray arrayWithObject:[CBUUID UUIDWithString:@"<uuid removed>"]] options:options];

The current state is:

  • In foreground mode the app quickly receives advertisement messages when I start my peripheral (within one second)

  • In background mode the app sometimes receives advertisement messages within like 10 seconds after starting the peripheral (which can be acceptable even if it is bad) however often it does not receive the advertisement for a very long time (minutes or more) and this does not work for the application.

Question is:

Is it in some way possible to increase the rate of which iOS is scanning for Bluetooth 4.0 LE peripherals when the scanning app is in background? Since I don't think there is a public API to do this, I am looking for a private API that is not published by Apple. This is for an internal enterprise app so a private API would be perfectly OK.

Maytime answered 19/10, 2013 at 22:19 Comment(2)
@jesnolsson How to find CBUUID when start app? i want do it in my project.Livable
You should probably write a new question on SO.. But to get you started just follow my code above. The actual UUID of the Services is specific to the kind of Bluetooth LE accessory you have so you need to look the actual numbers up. I would recommend LightBlue available on App Store for this purpose.Maytime
G
6

Background mode works differently for scanning.

  • Every peripheral is only reported the first single time it is observed (you cannot track proximity through RSSI without connecting to it while in background mode).

  • You can initiate a connect request to a peripheral that's not within range, and the connection will complete when the peripheral becomes available. Don't have to actively scan for this (except for initial discovery, so you know which UUID to connect).

Maybe, you can solve the problem by sending a connect request instead of scanning, while in background. This way, iOS knows that you are really interested in a specific peripheral and I could imagine that this affects discovery times.

Depending on your goal, a different approach could be to reverse the connection by placing the iPhone in peripheral mode and using your current LE peripherals in central mode. Seems hackish, but if it solves the problem for your case: why not :)

Regarding a private API: sorry, I don't know one that affects scanning parameters.

Garmon answered 26/10, 2013 at 10:47 Comment(5)
Thanks for the reply, that is very interesting, if I make the iPhone peripheral and the accessory in central mode, how often will the iPhone advertise itself? will the advertisement work well in background or will it suffer the same low speed of advertising as it does with scanning? Connect is not really fit for purpose since I want to get info from multiple peripherals. Maybe that is an issue as well if the iPhone is a peripheral since only one central can communicate with it?Maytime
The iPhone advertising interval depends on how frequently it was started (it becomes slower over time) and whether your app is backgrounded. It should work in background (need another background mode key in Info.plist), not sure about connection latencies (however, you can measure with a Bluetooth packet sniffer - note that you have to scan all 3 advertisement channels, as the iPHone cannot be configured to use only one). iPhone peripheral mode is not standard-conform and allows multiple centrals to connect.Garmon
@Etan, regarding your first point in your answer. CBCentralManager can listen (and NSLog) to centralManager:didDiscoverPeripheral: advertisementData: RSSI:, even while peripheral is in background, I get the RSSI. Are you referring to readRSSI? How is that different? ThanksLatchkey
You only get a single centralManager:didDiscoverPeripheral:advertisementData:RSSI: for every device while in background, unless you connect and disconnect again.Garmon
Or you stop the scan and restart it. With every new scan, all peripherals will be discovered again (including the RSSI)Sverige

© 2022 - 2024 — McMap. All rights reserved.