简体   繁体   English

iOS-如何在BLE外设上发现未发布的服务

[英]iOS - How to discover unadvertised services on a BLE peripheral

I got this Nordic nRF52 BLE peripheral which doesn't advertise its services. 我得到了这个不公布其服务的Nordic nRF52 BLE外围设备。 I'm able to connect to it, but can't discover services on iOS. 我可以连接到它,但是无法在iOS上发现服务。 Since I know the service UUIDs, I've tried to pass them to the discoverServices function. 由于我知道服务UUID,因此我尝试将它们传递给discoverServices函数。 But this does not work. 但这是行不通的。

After about 30 seconds it finally disconnects. 大约30秒后,它终于断开连接。

On the peripheral the GAP advertising flag is set to General Discoverable . 在外围设备上,GAP广告标记设置为“ General Discoverable Using apps like LightBlue or nRF Connect I see the name and UUID of the peripheral but no service. 使用LightBluenRF Connect类的应用程序,我看到外围设备的名称和UUID,但没有任何服务。 When connecting with the LightBlue app, after a few seconds an error ( Timeout interrogating the peripheral ) is shown. 当与LightBlue应用程序连接时,几秒钟后显示错误( Timeout interrogating the peripheral )。

On Android discovering the unadvertised services works just fine. 在Android上,发现未发布的服务就可以了。

As of the Core Bluetooth Programming Guide , it should basically work: 从《 核心蓝牙编程指南》开始 ,它基本上应该可以工作:

After you have established a connection to a peripheral, you can explore its data. 建立与外围设备的连接后,您可以浏览其数据。 The first step in exploring what a peripheral has to offer is discovering its available services. 探索外围设备必须提供的第一步是发现其可用的服务。 Because there are size restrictions on the amount of data a peripheral can advertise, you may discover that a peripheral has more services than what it advertises (in its advertising packets). 由于外围设备可以发布的数据量受到大小限制,因此您可能会发现外围设备提供的服务多于其发布的内容(在其广告包中)。 You can discover all of the services that a peripheral offers by calling the peripheral's discoverServices: method, like this: [peripheral discoverServices:nil]; 您可以通过调用外围设备的discoverServices:方法来发现外围设备提供的所有服务,如下所示: [peripheral discoverServices:nil];

Does anyone know what the differences in the SDKs are and if there is a possibility to discover unadvertised services on iOS like Android does? 有谁知道SDK的区别是什么,以及是否有可能像Android一样在iOS上发现未发布的服务?

I've read that iOS is capable of connecting directly, skipping the discovery process, when the peripheral is cached. 我了解到,缓存外设时,iOS能够直接连接,跳过发现过程。 But having the peripheral cached, it needs to be paired once. 但是将外围设备缓存后,需要配对一次。 Is there maybe a way to set the cache manually? 有没有办法手动设置缓存?

Appreciate any help, thanks! 感谢任何帮助,谢谢!

This sounds more like a problem in your firmware on the NRF52. 这听起来更像是NRF52上固件的问题。 I have been using NRF51 and NRF52 series for some years now and they definitely work with both iOS and Android devices. 我使用NRF51和NRF52系列已有数年了,它们肯定可以在iOS和Android设备上使用。

BLE advertising and service discovery BLE广告和服务发现

Some general information on BLE advertising and service discovery: 有关BLE广告和服务发现的一些一般信息:

A BLE advertising packet is very limited in size (31 bytes to be precise, not including the overflow area). BLE广告包的大小非常有限(准确地说是31个字节,不包括溢出区域)。 That means you cannot advertise all the services your peripheral supports and the space might be shared with other information as well (appearance, name, manufacturer data, etc.). 这意味着您无法宣传外围设备支持的所有服务,并且该空间也可能与其他信息(外观,名称,制造商数据等)共享。 You do not even have to advertise any service at all or can even advertise services that your peripheral does not support. 您甚至根本不需要广告任何服务,甚至可以广告您的外围设备不支持的服务。 The service discovery works regardless of the advertised services. 无论发现的服务是什么,服务发现均有效。

Debugging 调试

Some ideas for troubleshooting your problem: 解决问题的一些建议:

  1. iOS caches discovered services, characteristics and descriptors once they have been discovered until the next power cycle (turning Bluetooth off and on again or restarting the iOS device). 一旦发现服务,特征和描述符,iOS会对其进行缓存,直到下一个电源循环(关闭并重新打开蓝牙或重新启动iOS设备)为止。 This can lead to some unexpected behaviour if you have changed the underlying services etc. in your firmware but have not used the Services Changed Flag to indicate the change. 如果您已更改固件中的基础服务等,但未使用“服务已更改标志”来指示更改,则可能导致某些意外行为。 Therefore, make sure that you send the Services Changed flag from your peripheral accordingly. 因此,请确保相应地从外围设备发送“服务已更改”标志。

  2. Try some of the examples that come with the NRF5 SDK and check if they work. 尝试使用NRF5 SDK随附的一些示例,并检查它们是否有效。 If the examples work (which they should) there is definitely something wrong with your firmware. 如果这些示例正常工作(它们应该这样做),则固件肯定存在问题。

  3. Make sure that you handle the GAP and GATT events properly in your firmware. 确保在固件中正确处理了GAP和GATT事件。 Both iOS and Android devices are not 100% compliant with the Bluetooth 4.0+ standard. iOS和Android设备均不100%兼容Bluetooth 4.0+标准。 Nordic Semiconductor has already taken into account some of those quirks in their SDK and SoftDevice. Nordic Semiconductor已经在其SDK和SoftDevice中考虑了其中的一些问题。 You should definitely check the logs of the GAP and GATT events (basically the ble_evt_handler in your firmware) and refer to the Nordic Devzone where most of those quirks have been resolved already. 您绝对应该检查一下GAP和GATT事件的日志(基本上是固件中的ble_evt_handler),并参考Nordic Devzone中已解决了大多数怪癖的地方。

  4. Check the permissions for reading and writing the service and characteristic metadata in your firmware. 检查在固件中读写服务和特征元数据的权限。 I had a similar problem where I accidentally set the read permission of my characteristics to no access . 我有一个类似的问题,我不小心将特征的读取权限设置为no access

Hope that helps. 希望能有所帮助。

You can't discover unadvertised services because unadvertised means not reachable, disable etc. 您无法发现未发布的服务,因为未发布意味着无法访问,禁用等。

LighBlue show you UUID it's true, but it's device UUID not service UUID and that's the case. LighBlue向您显示UUID这是事实,但设备UUID服务UUID ,事实就是如此。

To scan peripheral device you can use CoreBluetooth . 要扫描外围设备,可以使用CoreBluetooth
CoreBluetooth is a framework which provides the classes needed for your apps to communicate with devices that are equipped with BLE. CoreBluetooth是一个框架,提供您的应用程序与配备BLE的设备进行通信所需的类。

You can start scanning peripheral devices with CoreBluetooth using method scanForPeripheralsWithServices:options: . 你可以开始扫描外围设备CoreBluetooth使用方法scanForPeripheralsWithServices:options: As a one of parameter of this method you need pass array of services UUIDs . 作为此方法的参数之一,您需要传递services UUIDs数组。
Discovered services will be available in method centralManager:didDiscoverPeripheral:advertisementData:RSSI: . 发现的服务将在方法centralManager:didDiscoverPeripheral:advertisementData:RSSI:可用。

On Android discovering services works just fine. 在Android上,发现服务可以正常工作。

It's true. 这是真的。 Android allow to scanning all available services around you. Android允许扫描您周围的所有可用服务。 Unfortunately iOS not. 不幸的是iOS没有。 Why? 为什么? Apple explain that: 苹果解释说:

Discovering all of a peripheral's services and associated characteristics can negatively affect battery life and your app's performance. 发现外围设备的所有服务和相关特征可能会对电池寿命和应用程序性能产生负面影响。 Therefore, you should look for and discover only the services and associated characteristics your app needs. 因此,您应该寻找并仅发现应用所需的服务和相关特征。

So, to get services UUID (because that's what we need to perform scanning using CoreBluetooth ) you can use Android app (kind of BLE scanner) or just read services UUID from box of your devices. 因此,要获取services UUID (因为这是我们需要使用CoreBluetooth进行扫描的CoreBluetooth ),您可以使用Android应用(某种BLE扫描仪)或仅从设备包装盒中读取services UUID

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM