【问题标题】:iOS - How to discover unadvertised services on a BLE peripheraliOS - 如何在 BLE 外围设备上发现未公布的服务
【发布时间】:2018-02-04 09:18:25
【问题描述】:

我得到了这个不宣传其服务的 Nordic nRF52 BLE 外围设备。我可以连接到它,但无法在 iOS 上发现服务。由于我知道服务 UUID,因此我尝试将它们传递给 discoverServices 函数。但这不起作用。

大约 30 秒后,它终于断开连接。

在外围设备上,GAP 广告标志设置为General Discoverable。使用 LightBluenRF Connect 之类的应用程序,我看到外围设备的名称和 UUID,但没有服务。与 LightBlue 应用程序连接时,几秒钟后会显示错误 (Timeout interrogating the peripheral)。

在 Android 上发现未公布的服务可以正常工作。

截至Core Bluetooth Programming Guide,它应该基本上可以工作:

与外围设备建立连接后,您可以探索其数据。探索外设必须提供什么的第一步是发现其可用服务。由于外围设备可以通告的数据量存在大小限制,因此您可能会发现外围设备的服务比它所通告的(在其通告数据包中)要多。您可以通过调用外设的 discoverServices: 方法来发现外设提供的所有服务,如下所示:[peripheral discoverServices:nil];

有谁知道 SDK 的区别是什么,以及是否有可能像 Android 一样在 iOS 上发现未经宣传的服务?

我了解到,当外围设备被缓存时,iOS 能够直接连接,跳过发现过程。但是缓存了外围设备,它需要配对一次。有没有办法手动设置缓存?

感谢任何帮助,谢谢!

【问题讨论】:

  • “我可以连接到它,但在 iOS 上找不到服务。”:你能展示一下你的代码吗?你设置代理了吗?您是否在CBPeripheral 上保留了强引用(这通常是 CoreBluetooth 上的常见错误。框架倾向于不保留强引用,并且由于委托调用是“异步”的,它会忘记外围设备的存在)。?跨度>
  • 事实并非如此。此行为发生在 Appstore 中的多个应用程序中。正如@jens-meder 指出的那样,可能是固件问题。
  • 嘿@jim 我可以看到您找到了解决问题的方法,请您稍微扩展一下。我有同样的问题,除了它只发生在我们用户的一台 iPad 上(所有其他设备都可以正常工作)
  • 嗨,西蒙。由于这只发生在一台设备上,我认为这是一个不同的问题。服务 UUID 是否更改?是否可以与 LightBlue 连接?您是否尝试过 Jens 回答中的第 1 点?

标签: ios bluetooth-lowenergy gatt


【解决方案1】:

这听起来更像是您的 NRF52 上的固件存在问题。几年来我一直在使用 NRF51 和 NRF52 系列,它们绝对适用于 iOS 和 Android 设备。

BLE 广告和服务发现

关于 BLE 广告和服务发现的一些一般信息:

BLE 广告包的大小非常有限(准确地说是 31 个字节,不包括溢出区域)。这意味着您不能宣传您的外围设备支持的所有服务,并且该空间也可能与其他信息(外观、名称、制造商数据等)共享。您甚至根本不需要宣传任何服务,甚至可以宣传您的外围设备不支持的服务。无论广告的服务如何,服务发现都会起作用。

调试

解决问题的一些想法:

  1. 一旦发现服务、特征和描述符,iOS 就会缓存它们,直到下一次电源循环(关闭并再次打开蓝牙或重新启动 iOS 设备)。如果您更改了固件中的底层服务等,但没有使用服务更改标志来指示更改,这可能会导致一些意外行为。因此,请确保相应地从外围设备发送 Services Changed 标志。

  2. 尝试一些 NRF5 SDK 附带的示例并检查它们是否有效。如果示例有效(它们应该有效),那么您的固件肯定有问题。

  3. 确保在固件中正确处理 GAP 和 GATT 事件。 iOS 和 Android 设备都不是 100% 符合蓝牙 4.0+ 标准。 Nordic Semiconductor 已经在其 SDK 和 SoftDevice 中考虑了其中的一些怪癖。您绝对应该检查 GAP 和 GATT 事件的日志(基本上是固件中的 ble_evt_handler),并参考 Nordic Devzone,其中大部分问题已经解决。

  4. 检查在固件中读写服务和特征元数据的权限。我有一个类似的问题,我不小心将我的特征的读取权限设置为no access

希望对您有所帮助。

【讨论】:

  • 感谢您的好建议!缓存不是问题,所以很可能是固件问题!我会对此进行调查。
  • 解决了!问题是固件没有响应BLE_GATTS_EVT_EXCHANGE_MTU_REQUESTBLE_GATTS_EVT_SYS_ATTR_MISSING。这导致 CoreBluetooth 超时,从而关闭了连接。非常感谢您的帮助。
【解决方案2】:

您无法发现未广告服务,因为未广告意味着无法访问、禁用等。

LighBlue 告诉你 UUID 是真的,但它是 设备 UUID 而不是 服务 UUID 就是这样。

要扫描外围设备,您可以使用CoreBluetooth
CoreBluetooth 是一个框架,它提供您的应用与配备 BLE 的设备通信所需的类。

您可以使用方法scanForPeripheralsWithServices:options: 开始扫描外围设备CoreBluetooth。作为此方法的参数之一,您需要传递services UUIDs 的数组。
发现的服务将在方法 centralManager:didDiscoverPeripheral:advertisementData:RSSI: 中可用。

在 Android 上发现服务工作正常。

这是真的。 Android 允许扫描您周围的所有可用服务。不幸的是iOS没有。为什么?苹果解释说:

发现所有外围设备的服务和相关特征可能会对电池寿命和应用性能产生负面影响。因此,您应该只寻找和发现您的应用所需的服务和相关特征。

所以,要获得services UUID(因为这是我们使用CoreBluetooth 执行扫描所需的),您可以使用Android 应用(一种BLE 扫描仪)或从设备包装盒中读取services UUID

【讨论】:

  • 感谢您的努力,但您所描述的基本上就是我正在做的。此外,Apple 的解释对应于discoverServices 函数。通过提供 UUID,您可以更快地发现服务。
  • 谢谢@Mateusz 你完全确定吗?这是否意味着在使用 iOS 时,我不能使用没有被宣传的服务?你有那个链接吗?我试图找到它,但我找不到。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2015-01-26
  • 2015-06-29
  • 2014-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-08
相关资源
最近更新 更多