BLE 扫描未知服务

Posted

技术标签:

【中文标题】BLE 扫描未知服务【英文标题】:BLE Scanning for unknown service 【发布时间】:2015-12-27 23:28:58 【问题描述】:

我正在尝试编写一个玩具应用程序来快速了解 BLE。我有一个外围设备(它是Tile),我想扫描它的服务。但是,我不知道它提供了哪些服务(而且我在产品的技术规范中也没有看到这一点)。所以,我从蓝牙规范中得到了一个list of services,并试图扫描所有这些。我只是假设这个列表是详尽无遗的,因为它没有说明任何一种方式。

这是我的代码:

- (void)viewDidLoad 
    [super viewDidLoad];    

    // Scan for all available CoreBluetooth LE devices
    _services = @[[CBUUID UUIDWithString:@"1811"],
                  [CBUUID UUIDWithString:@"1815"],
                  [CBUUID UUIDWithString:@"180F"],
                  [CBUUID UUIDWithString:@"1810"],
                  [CBUUID UUIDWithString:@"181B"],
                  [CBUUID UUIDWithString:@"181E"],
                  [CBUUID UUIDWithString:@"181F"],
                  [CBUUID UUIDWithString:@"1805"],
                  [CBUUID UUIDWithString:@"1818"],
                  [CBUUID UUIDWithString:@"1816"],
                  [CBUUID UUIDWithString:@"180A"],
                  [CBUUID UUIDWithString:@"181A"],
                  [CBUUID UUIDWithString:@"1800"],
                  [CBUUID UUIDWithString:@"1801"],
                  [CBUUID UUIDWithString:@"1808"],
                  [CBUUID UUIDWithString:@"1809"],
                  [CBUUID UUIDWithString:@"180D"],
                  [CBUUID UUIDWithString:@"1823"],
                  [CBUUID UUIDWithString:@"1812"],
                  [CBUUID UUIDWithString:@"1802"],
                  [CBUUID UUIDWithString:@"1821"],
                  [CBUUID UUIDWithString:@"1820"],
                  [CBUUID UUIDWithString:@"1803"],
                  [CBUUID UUIDWithString:@"1819"],
                  [CBUUID UUIDWithString:@"1807"],
                  [CBUUID UUIDWithString:@"1825"],
                  [CBUUID UUIDWithString:@"180E"],
                  [CBUUID UUIDWithString:@"1822"],
                  [CBUUID UUIDWithString:@"1806"],
                  [CBUUID UUIDWithString:@"1814"],
                  [CBUUID UUIDWithString:@"1813"],
                  [CBUUID UUIDWithString:@"1824"],
                  [CBUUID UUIDWithString:@"1804"],
                  [CBUUID UUIDWithString:@"181C"],
                  [CBUUID UUIDWithString:@"181D"]];

    CBCentralManager *centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    [centralManager scanForPeripheralsWithServices:_services options:nil];
    self.centralManager = centralManager;


- (IBAction)scanForDevices:(UIButton *)sender 
    [_centralManager scanForPeripheralsWithServices:_services options:nil];


// CBCentralManagerDelegate - This is called with the CBPeripheral class as its main input parameter.
// This contains most of the information there is to know about a BLE peripheral.
- (void)centralManager:(CBCentralManager *)central
 didDiscoverPeripheral:(CBPeripheral *)peripheral
     advertisementData:(NSDictionary *)advertisementData
                  RSSI:(NSNumber *)RSSI

    NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
    if ([localName length] > 0) 
        NSLog(@"Found the heart rate monitor: %@", localName);
        [self.centralManager stopScan];
        _hRMPeripheral = peripheral;
        peripheral.delegate = self;
        [self.centralManager connectPeripheral:peripheral options:nil];
    


// method called whenever the device state changes.
- (void)centralManagerDidUpdateState:(CBCentralManager *)central

    // Determine the state of the peripheral
    if ([central state] == CBCentralManagerStatePoweredOff) 
        NSLog(@"CoreBluetooth BLE hardware is powered off");
    
    else if ([central state] == CBCentralManagerStatePoweredOn) 
        NSLog(@"CoreBluetooth BLE hardware is powered on and ready");
    
    else if ([central state] == CBCentralManagerStateUnauthorized) 
        NSLog(@"CoreBluetooth BLE state is unauthorized");
    
    else if ([central state] == CBCentralManagerStateUnknown) 
        NSLog(@"CoreBluetooth BLE state is unknown");
    
    else if ([central state] == CBCentralManagerStateUnsupported) 
        NSLog(@"CoreBluetooth BLE hardware is unsupported on this platform");
    

我得到的唯一日志输出是这样的:

CoreBluetooth BLE 硬件已开机并准备就绪

否则,应用程序运行良好。没有错误或警告。但它永远找不到外围设备。

我做错了什么?我应该扫描其他服务吗?

谢谢!

编辑 使用下面的建议,我使用 LightBlue 应用程序扫描了外围设备。我现在知道有一个广告服务使用这个 UUID:

84100CBF-D622-8FF7-C8B8-300FDB52B92D

我将数组更改为如下所示:

_services = @[[CBUUID UUIDWithString:@"84100CBF-D622-8FF7-C8B8-300FDB52B92D"]];

但日志中仍然没有任何输出。我也尝试通过nil,但仍然没有。

【问题讨论】:

只需提供nil 服务,即可扫描并记录您收到的内容或使用 App Store 中的 LightBlue 等应用程序。 谢谢。我之前尝试过使用nil,但也没有产生任何结果。 LightBlue 是个好主意。我现在知道广告数据包的 UUID,我将其插入我的NSArray。但是,仍然没有日志输出。我的代码一定有问题。 @androidDev 你把附近所有可用的设备都弄到了吗 【参考方案1】:

正如 Paulw 所指出的,只需发送 nil 而不是服务列表,您将获得范围内的所有外围设备,无论它们宣传什么服务。

注意:

这只能在前台工作。后台扫描需要您提供扫描服务 在您的方法中,不可能列出所有服务。除了您列出的具有短 UUID 的服务(实际上是完整 UUID 的快捷方式)之外,设备还可以宣传具有任何“完整”UUID 的服务。有 2^128 个可能的值...

【讨论】:

谢谢。我没有意识到 UUID 实际上是服务号。我并不惊讶这些比蓝牙网站上列出的要多得多。我试过nil 但什么也没得到,所以我的代码一定有问题。我还使用 LightBlue 来获取广告服务的确切 UUID 并将其放入我的数组中。依然没有。你看到代码有什么问题吗?再次感谢! 只有在调用centralManagerDidUpdateState:且状态为CBCentralManagerStatePoweredOn时才开始扫描。 是的,我是,但现在我意识到没有更改按钮中的扫描指令以包含nil 作为参数(我只在viewDidLoad 中更改了它)。一旦我改变它就出现了。非常感谢您的帮助!

以上是关于BLE 扫描未知服务的主要内容,如果未能解决你的问题,请参考以下文章

BLE 扫描记录 - 未获取所有广告数据(服务数据)

为啥在 IntentService 中进行的 BLE 扫描即使在服务被破坏时也能继续工作?

BLE扫描不工作

iOS - 在后台扫描 BLE 设备

在 iOS 后台实现 BLE 扫描

如何从 C++ 代码扫描和连接广告 BLE 设备?