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

Scanning for Peripherals offering specific services, But doesn't find Services on discovered peripheral

我正在为 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) 来发现任何服务,但仍然没有响应。

谁能帮我找出问题所在?

当您扫描CBPeripheral 对象时,外围服务UUID 是从广告数据包中获取的。外围设备基本上是说,"Oh yeah, I have this service UUID!" iOS 将其拾取并将 CBPeripheral 传递给您。

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

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

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