我正在使用 Xamarin.iOS 编写一个 BLE 扫描器。 我有兴趣获取设备的 GUID 及其关联的 2 个词,最后是计算手机和 BLE 信标之间距离的信号强度。 信标使用 iBeacon 协议。
这是我目前的伪代码:
if (scanner == null)
{
scanner = new CBCentralManager();
}
if (scanner != null)
{
// FIXME Should I pass null to the first parameter of ScanForPeripherals?
scanner.DiscoveredPeripheral += Scanner_DiscoveredPeripheral;
scanner.ScanForPeripherals(null, new PeripheralScanningOptions { AllowDuplicatesKey = true });
}
private void Scanner_DiscoveredPeripheral(object sender, CBDiscoveredPeripheralEventArgs e)
{
lock (this.visibleBeacons)
{
// FIXME : How do I get the 2 word values and the signal strength?
BeaconInfo discoveredPeripheral = new BeaconInfo(e.Peripheral.Identifier.ToString(), word1, word2, signalStrength);
...
}
}
我们从不打开带有信标的会话来接收数据。我们仅依靠广告特性(每 250 毫秒发送一次)来满足我们的业务需求。 2 个 16 位字段用于告诉我们在信标附近行走时需要做什么。
信标使用制造商软件进行编程。
要使用 Xamarin.iOS 获取 BLE 信标的 GUID、2 字值和信号强度,您可以按如下方式修改代码:
要获取设备的GUID,可以使用在DiscoveredPeripheral事件中传递的CBPeripheral对象的Identifier属性。
要获得 2 字值,您需要从 iBeacon 发送的广告包中提取它们。 2 个字值实际上是 iBeacon 广告数据包的一部分,特别是在制造商特定数据字段中。您可以从广告数据包中提取此字段,然后从中提取 2 个字值。 Manufacturer Specific Data字段的结构如下:
您可以使用在 DiscoveredPeripheral 事件中传递的 CBPeripheral 对象的 AdvertisementData 属性来提取广告数据包。广告数据的 ManufacturerData 属性包含 Manufacturer Specific Data 字段。 要获得信号强度,您可以使用在 DiscoveredPeripheral 事件中传递的 CBPeripheral 对象的 RSSI 属性。 获得 GUID、2 个字值和信标的信号强度后,您可以使用信号强度使用路径损耗模型估计手机与信标之间的距离。路径损耗模型基于信号强度随着手机和信标之间的距离增加而降低的事实。您可以使用以下公式来估算距离:
距离 = 10 ^((测量功率 - 信号强度)/(10 * n))
其中测量功率是距信标 1 米处的信号强度(从制造商特定数据字段中提取),信号强度是接收信号的信号强度(由电话测量),n 是路径损耗指数(通常2 和 4 之间)。路径损耗指数取决于信标部署的环境,可以根据经验确定。
不幸的是,您不能使用 Apple 的 CBCentralManager 框架来扫描 iBeacon。 Apple 主动阻止该 API 检测任何 iBeacon 数据包。请参阅我的博客文章here.
作为替代方案,您需要使用 Apple
CoreLocation
API。我不是 Xamarin 专家,但您可能想看看这个 code sample 看看这是如何完成的。