有没有一种更快地发现BLE外设服务的方法?

5

我发现我的iOS7中BLE协议的实现在启动阶段非常缓慢。启动序列占据了应用程序整个执行时间的约68%。

我该如何使其更快?

我已经计时,以下是我的结果。

     t     dt   
37.598          [BLE] Discovered peripheral at RSSI -27 with UUID:XYZ
37.599  0.001   [BLE] Connecting to peripheral                                                                            
37.602  0.003   [BLE] Scanning stopped                                                                                           
37.685  0.083   [BLE] Peripheral connected                                                                                
38.48   0.795   [BLE] Discovered service  
38.599  0.119   [BLE] Discovered characteristic    

正如您所看到的,在发现服务之前存在着一个巨大的瓶颈。

我的创业公司代码简化后:

- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    switch (central.state) {
        case CBCentralManagerStatePoweredOn:
            [central scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUuid]]
                                            options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @YES}];
            break;
        case CBCentralManagerStatePoweredOff:
            [central stopScan];
            break;
        default:
            break;
    }
}

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    if (self.discoveredPeripheral != peripheral) {
        self.discoveredPeripheral = peripheral; // Save a local copy of the peripheral, so CoreBluetooth doesn't get rid of it
        [central connectPeripheral:peripheral options:nil];
        [central stopScan];
    }
}

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    [peripheral discoverServices:@[[CBUUID UUIDWithString:kServiceUuid]]];
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
    for (CBService *service in peripheral.services) {
        [peripheral discoverCharacteristics:@[array of characteristics]
                                 forService:service];
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    ...
}

编辑

我了解到安卓上类似的应用程序执行速度比这快十倍(使安卓应用感觉更加迅捷 -> 更好的用户体验),因此我很好奇是我的实现、BLE层还是硬件成为了瓶颈。它在iPhone 4S上进行了测试。


我很好奇你花了多长时间发现外设。我猜测发现外设及其服务所需的时间与它们的硬件实现有关。 - reTs
根据我的经验,广告宣传速率更高的外围设备将花费更短的时间来发现服务。也许这只是巧合,因为我只有很少的外围设备可以使用。此外,我发现外围设备发现服务所需的最长时间约为0.5秒,这对我来说是可以接受的。 - reTs
我已经测试了两个完全不同(硬件方面)的外设,结果是相同的(误差在50毫秒左右)。我不确定如何测量发现外设之前的时间?尽管如此,发现外设和发现服务之间的时间差仍然相当显著,因为它会使应用程序感觉比它本来可以更流畅。 - MdaG
你用了什么类型的设备?我尝试使用CiragoBLE BT8000 dongle,但它无法检测到。请列出一些在iOS中可以检测到的蓝牙dongle。提前致谢! - user559005
1
我没有使用dongle,而是使用一个专门用于与BLE设备(不仅限于iOS设备)通信的独立BLE外设。您是否尝试使用LightBlue检测您的dongle?https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8 - MdaG
2个回答

4

当您加密连接时,iOS应该缓存GATT数据库。因此,第一次之后的后续发现调用应该立即发生。

自iOS 7以来,即使是特征值也被缓存,这意味着您可以通过特征值属性读取静态值,如“设备名称”。如果要更新它们,则仍需发出“读取特征值”请求。

有关缓存行为的详细信息,请查看WWDC 2013会议703,从幻灯片48开始(可能需要观看视频中相应部分)。

对于连接和发现时间,主要取决于广告间隔。苹果在Apple产品蓝牙附件设计指南第3.5节广告间隔中推荐了几个广告间隔以获得最佳性能。此外,在连接时应禁用扫描,因为扫描会将连接过程减慢约55倍。

请注意,基于iOS的每个连接事件发送数据包的限制不应明显影响发现时间(除非您有一个巨大的GATT数据库并且正在查询整个内容)。这些限制只应在“写入无响应”和“特征值通知”时变得可见,根据LE协议设计。


你发布的 WWDC 2013 session 703 的链接已经失效,请更新为以下链接:https://developer.apple.com/videos/wwdc/2013/?id=703 - GoRoS

1

没有框架级别的API可以提高发现速度。BTLE与Classic Bluetooth(在系统框架级别)和Wi-Fi(在天线级别)共存,因此天线上的最大时间受系统限制。


那么这是硬件相关的吗?那就可以解释为什么Android应用程序更快了。 - MdaG
大体上是这样的,我想在安卓手机上你可能会看到一些响应性方面的差异:不同的芯片组和天线布局将决定不同的共存要求。 - cbowns

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接