The Low Energy Bluetooth spec does not say much about whether peripherals can connect to more than one central at a time, but my experience testing tells me that they cannot.
Because my application requires a non-possessive relationship with peripherals (i.e. no connections, which would block others), and needs to constantly update their RSSI values, I am seeking a way to continuously scan for peripherals and capture their RSSI values.
The scanForPeripheralsWithServices method appears to scan for a certain interval and then stops. I believe my best bet is to scan for 3 seconds at a time, stopScan, wait (several seconds) and then reinitiate a scan. Repeat.
Can anyone point to a better way of doing it? For example, configuring a peripheral to connect to more than one Central?
I solved this type of issue with this code, basically just restarting the scanning every time an advertisement is processed. I was facing the same issue where CBCentralManager instance would stop listening to a peripheral.
(Setting CBCentralManagerScanOptionAllowDuplicatesKey
to @YES
did not fully solve the issue for me.)
Assuming the class implements CBCentralManagerDelegate:
- (id) init {
self.central = [[CBCentralManager alloc]initWithDelegate:self queue:nil];
[self initScan];
}
- (void) initScan {
[self.central stopScan];
[self.central scanForPeripheralsWithServices:nil
options:[NSDictionary dictionaryWithObjectsAndKeys:@NO, CBCentralManagerScanOptionAllowDuplicatesKey, nil]];
}
- (void) centralManager:(CBCentralManager*)central didDiscoverPeripheral:(CBPeripheral*)peripheral advertisementData:(NSDictionary*)advertisementData RSSI:(NSNumber*)RSSI {
//
// Do stuff here
//
[self initScan];
}
A peripheral cannot connect to more than one central. But if you need to just capture the RSSI then you don't even need connecting. Scanning for devices can retrieve the RSSI using this function:
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
As for the previous answer, if you are interested only in RSSI you can simply get it into the delegate method:
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
BTW, by default the CBCentralManager
will only call this method once. If you need this callback to be called every time the CBCentralManager
receives an advertisement packet you need to initiate the scan with the option CBCentralManagerScanOptionAllowDuplicatesKey
set to YES
:
NSDictionary *scanningOptions = @{CBCentralManagerScanOptionAllowDuplicatesKey: @YES};
[centralManager scanForPeripheralsWithServices:nil options:scanningOptions];
Beware that Apple discourage the usage of this option if not strictly necessary.
See: iOS Developer Library -Best Practices for Interacting with a Remote Peripheral Device
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With