扫描提供特定服务的外围设备,但在发现的外围设备上找不到服务

Posted

技术标签:

【中文标题】扫描提供特定服务的外围设备,但在发现的外围设备上找不到服务【英文标题】:Scanning for Peripherals offering specific services, But doesn't find Services on discovered peripheral 【发布时间】:2016-03-04 12:50:21 【问题描述】:

我正在试验适用于 ios 的 CoreBluetooth 框架,但遇到了一个我觉得很奇怪的问题。

一旦我有一个连接的外围设备,我想发现它的服务 - 但它失败了。尽管搜索并找到提供特定服务的外围设备。请看下面的代码:

func centralManagerDidUpdateState(central: CBCentralManager) 
    if(central.state != .PoweredOn) 
        print("Returning due to wrong state: ", central.state)
        return;
    
    print("Starting peripheral scan")
    manager.scanForPeripheralsWithServices(serviceUUID, options: nil)

外围扫描已启动并查找指定的服务 UUID。在这种情况下:serviceUUIDs = [CBUUID(string: "13333333-3333-3333-3333-333333333337")]。如果我更改字符串,则根本没有发现任何服务(如预期的那样)。

func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) 
    print("Discovered peripheral: ", peripheral.name)
    if(peripheral.name == "PizzaSquat") 
        print("Advertising data: ", advertisementData)
        print("RSSI: ", RSSI)
        activePeripheral = peripheral
        print("Connecting to peripheral")
        manager.connectPeripheral(peripheral, options: nil)
    

在 Linux 计算机上,我有一个 Bleno 实例正在运行,它显示为一个名为“PizzaSquat”的外围设备(显然提供了一项服务,因为它已经被发现了。所以当这个外围设备被发现时,我连接给它。

func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) 
    print("Connected to Peripheral: ", peripheral.name)
    if(peripheral.services == nil) 
        print("Starting service discovery")
        peripheral.delegate = self
        peripheral.discoverServices(serviceUUIDs)
     else 
        print("Already has services: ")
        for service: CBService in peripheral.services! 
            print(service)
        
    

一旦连接(到“PizzaSquat”),我检查它是否已经有服务(它没有)并启动服务发现。到目前为止,一切都是正确的 - 但从未发现任何服务。我希望调用以下函数:

func peripheral(peripheral: CBPeripheral, didDiscoverServices error: NSError?) 
    print("Discovered new Service")
    for service: CBService in peripheral.services! 
        print(service)
    

至少有一项服务,因为如果外围设备没有指定的服务,则根本不应该被发现!

我也尝试调用peripheral.discoverServices(nil) 来发现任何服务,但仍然没有响应。

有人可以帮我找出问题吗?

【问题讨论】:

在 Objective-C 中是这样,不确定 Swift,但我想是一样的,但你应该保留 CBPeripheral 的引用。 我不明白为什么 Swift 和 Objective C 之间会有区别......是的,我之前陷入了那个陷阱。我在didDiscoverPeripheral 中保留了带有activePeripheral = peripheral 的CBPeripheral 我的错,我错过了activePeripheral 的行。 没问题,隐藏的很好:) 我建议您从 App Store 下载 LightBlue 应用程序,并检查它是否可以正确看到您的外围设备的服务。 【参考方案1】:

当您扫描 CBPeripheral 对象时,会从广告包中获取外围服务 UUID。外围设备基本上是在说,“哦,是的,我有这个服务 UUID!” iOS 会拾取它并将 CBPeripheral 传递给您。

但外围设备可能无法与广告数据包中的内容同步。广告数据包与外围设备的服务/特征层次结构中的实际内容相匹配,这是一个非约束性协议。

所以这意味着外围设备可以宣传一个服务 UUID,但实际上包含另一个(或没有)。

查看 iOS 上的 LightBlue 或 android 上的 nRF 控制面板,看看服务/特征层次结构是否与您认为的相符。在 LightBlue 中,您应该能够查看广告数据并将其与您连接的外围设备上的服务进行比较。

【讨论】:

以上是关于扫描提供特定服务的外围设备,但在发现的外围设备上找不到服务的主要内容,如果未能解决你的问题,请参考以下文章

扫描设备和服务时找不到外围设备,iPad 3 丢失

使用基于广告服务 UUID 的扫描过滤器扫描 BLE 外围设备

如何在 Android 中获取当前连接的 BLE 外围设备

使用核心蓝牙 ios 扫描外围设备时如何更改特征顺序

来自 2 个 BLE 设备的 ios 通知

Swift 3:如何在后台扫描外围设备?