2

我试图解决的基本问题如下。我有两台 iOS 设备,一台配置为中央设备,另一台配置为外围设备。我希望外围设备知道中央是否因某种原因移开或变为非活动状态(例如运行中央的设备已关闭)。

在正常情况下,我进行了设置,以便当中心靠近外围设备时,中心可以使用信标区域和测距通过特征写入通知外围设备(CLProximityImmediate),然后当它仍在范围内但距离很远(CLProximityFar)时再次出现。这很好用。

但是,当中央设备从 CLProximityImmediate 变为某个未知状态时,为了捕捉角落状况,我计划使用中央设备可以响应的外围设备的周期性指示。如果对指示没有响应,则外围设备可以假定中央不再紧邻。但是,我找不到通知外围管理器指示失败的回调或委托方法。

updateValue:forCharacteristic:onSubscribedCentrals: 方法在底层传输队列已满时返回 NO - 而不是因为中央没有响应,我理解它的方式。

我在这里遗漏了一些明显的东西吗?外围管理器有没有办法告诉中央没有收到指示?或者这种情况下 CoreBluetooth 中是否缺少回调?

谢谢你的帮助!

4

2 回答 2

5

There are two issues to let the peripheral know the location maneager lost contact with the CLBeacon:

  1. The iBeacons are passive, advertise and transmit only devices. As in the Apple implementation there are no connection made to them from the Core Location framework. Therefore the peripheral newer knows anyone listened to their broadcast.

  2. The CLBeacon will not expose the underlying BTLE peripheral as a CBPeripheral, so you would not be able to let the BTLE peripheral know your location monitor was in range.

Issue #2 can be resolved a rather complicated way:

  1. Start scanning for CBPeripherals where the advertisementData contains the proximityUUID.

  2. Make connections to that CBPeripheral and get notified of a characteristic value change.

  3. Change a characteristic value on the peripheral frequently, so when the Central sees no more notifications after a timeout period it indicates the peripheral is out of range.

  4. If you want to make it work for multiple iOS devices this gets way to complicated to switch between advertising and iBeacon and working as a GATT peripheral.

于 2013-10-05T23:58:32.003 回答
3

尽管问题中没有明确说明这一点,但我隐含地指出,外围设备正在宣传具有几个特征的服务。这是对明确的 iBeacon 广告的补充,我同意这是“被动的”。当中心被通知信标区域时,它发现并写入其中一个特征,外围设备可以知道中心在范围内。

我的基本问题不是关于信标的被动性质,而是更多关于“指示”如何与 CoreBluetooth 一起工作。我认为可以相当肯定地说,如果外围设备用于updateValue:forCharacteristic:onSubscribedCentrals:通知中央订阅了定义为的特征CBCharacteristicPropertyIndicate,则没有定义回调来捕获对应该从中央返回的指示的确认(每个 GAP)。

解决此缺失 API 的一种方法是将第三个特征定义为“确认”特征,并强加一个协议,即当中心接收peripheral:didUpdateValueForCharacteristic:到已订阅的指示时,中心应对该特征进行虚拟读取。这应该会peripheralManager:didReceiveReadRequest:在外围设备上产生一个调用,以确认收到了指示。

这是更多的工作,而不是最优雅的方法,但考虑到没有用于指示确认的 API,这可能是最好的方法。

于 2013-10-17T23:14:02.097 回答