Andras and Etan, thank you for your replies.
Regrading bonding the devices — I know that if I return CBATTErrorInsufficientAuthentication as response result from peripheral device it raises the pairing dialog. But I can not find any documentation of how to check what is the encryption level or authentication of the central device connected. Do you know if such documentation or API exist?
I do use UUID to identify previously connected devices.
I will try to describe my scenario in a different words.
The Central app works with many(dozens) of peripheral devices. I use iOS peripheral devices for prototyping but it will be both iOS and custom peripheral devices in the end. As number of devices is definitely greater than maximum BLE connections limit so I can not keep connection with all devices.
New devices may appear in range as well as known devices may disappear.
I found, that with CBCentralManagerScanOptionAllowDuplicatesKey = NO CBPeripheral instances are not duplicated within one "scan cycle"(between startScan and stopScan). If scan was restarted peripheral devices are discovered as the same instances of CBPeripheral until device's random changes.
The very first iteration works perfect, I read the data from devices sequentially and right after this I have a dilemma either to keep the CBPeripheral instance retained for the future connectionB or release it right after didDisconnect callback, and rely on next scan cycle.
1) If I release the CBPeripheral instance after I receive didDisconnect callback, the peripheral device is being discovered later as the same CBPeripheral instance during the next scan cycle and it will not discover it's services after connection with 100% reproducibility , so for sure this does not work.
2) In case if I keep the CBPeripheral instance retained then future connections work fine until the peripheral device changes it's random and being rediscovered by Central application as a new instance of CBPeripheral. At this moment previous instance of the CBPeripheral still remains connectable and readable, but new one gives me continuous connection errors, even when the previous one is not connected. Also, previous instance is not discovered on scan restart anymore, but new one is discovered contstantly. Releasing of the old instance does not make any sense, as new instance still remains non-connectable.
All connections are done with scanning turned off.
I have similar approach working with BlueGiga BLE112 as a Central device, but there I have an access to the peripheral's random and I don't have difficulties recognizing devices.
I would appreciate any hints on how to implement such approach with iOS, as for now I see only these 2 options how to handle reconnection, and both of them have issues.
From: Andras Kovi < email@hidden> Date: Thu, 21 Feb 2013 02:04:16 -0500 To: Maxim Ignatyev < email@hidden> Cc: " email@hidden" < email@hidden> Subject: Re: Re-connection to peripheral and service/characteristics discovery after disconnection or after BLE mac renewal.
Hi Maxim,
1. Scanning and connecting at the same time is not a good idea. You should stop scanning while trying to connect to a peripheral. 2. Yes, CB will return a new CBPeripheral each time. The UUID is used to identify, don't make any other assumptions on the object. The UUID will be nil before you ever connected to the device, after that he UUID assigned internally during the connection will be retrieved. 3. Duplicates are filtered out only in the scope of one scanning. If you stop and restart, the filtering will be reset. If you need more advanced filtering, then you need to implement it. 4. You should not release the peripheral before the didDisconnect callback is returned. You will receive warnings otherwise, even if the peripheral is being disconnected.
The most important is to avoid scanning and connecting at the same time. I can imagine that this causes the stall. However, if things don't get better, you should file a bug and let Apple support know as much as possible about your issue.
Regards, Andras
On 2013.02.21., at 2:48, Maxim Ignatyev < email@hidden> wrote: I'm developing the CBCentral iOS app that is not supposed to keep persistent connection to the peripheral devices but still need to periodically read data from them. Most of the peripherals now are iPhones that implement CBPeripheral part.
Central application always run in a foreground and has CBCentralManagerScanOptionAllowDuplicatesKey set to NO.
The flow is the following: 1. Timer tick(e.g. 1 minute) 2. Restart scan 3. Discover peripheral 4. If it's new peripheral then retain it OR if it's already retained peripheral and it's time to update the value then connect -> discover services -> discover characterictics -> write to characterictic -> receive characterisctic value updates -> disconnect.
At some point previously discovered peripheral device is being discovered as a new instance of CBPeripheral, I think it happens when peripheral changes it's mac address.
For this newly discovered CBPeripheral instance communication flow gets stuck on either service discovery, characteristics discovery, writing to characterictics or receiving characterisctic value updates. I'm 100% sure that previous CBPeripheral instance of this device is not connected at that moment.
Similar issue happens if I release CBPeripheral instance right after I receive centralManager:didDisconnectPeripheral:error: event for it. The same instance is discovered later on next timer tick and communication flow stucks on service discovery.
My questions are: 1) What is the best practice of handling periodical connections(if there is any)? 2) How to handle discovery of previously discovered device as a new instance of CBPeripheral?
I would be very appreciated for any help on this.
Thank you,
Maxim Ignatyev
|