16

众所周知,iOS 6 支持运行设备(iPhone 4s 及更高版本,以及新 iPad)作为 BLE 外围设备。WWDC 2012 Session 705 中有一个名为“高级核心蓝牙”的演示。我向 Apple 索要源代码。他们向我发送了源代码的修改版本 (BTLE_Transfer_Draft)。然后我:

  • 在 iPhone 5 (iOS 6) 中以“外围模式”运行应用程序并启动“广告”
  • 在“中央模式”下在新 iPad (iOS 5.1.1) 中运行应用程序

问题是外围设备根本没有被发现。所以我使用其他测试应用程序,包括一些从 App Store 下载的应用程序。都未能发现外围设备。我认为问题应该出在 BTLE_Transfer_Draft。因为我不确定是否允许我展示整个源代码。所以我在这里只展示“外围模式”部分:

- (void)viewDidLoad {
    [super viewDidLoad];

    // Start up the CBPeripheralManager
    _peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
}

- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
    // Opt out from any other state
    if (peripheral.state != CBPeripheralManagerStatePoweredOn) {
        return;
    }

    // We're in CBPeripheralManagerStatePoweredOn state...
    NSLog(@"self.peripheralManager powered on.");

    // ... so build our service.

    // Start with the CBMutableCharacteristic
    self.transferCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]
                                                                  properties:CBCharacteristicPropertyNotify
                                                                       value:nil
                                                                 permissions:CBAttributePermissionsReadable];

    // Then the service
    CBMutableService *transferService = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]
                                                                    primary:YES];

    // Add the characteristic to the service
    transferService.characteristics = @[self.transferCharacteristic];

    // And add it to the peripheral manager
    [self.peripheralManager addService:transferService];
}

/** Start advertising
 */
- (IBAction)switchChanged:(id)sender
{
    if (self.advertisingSwitch.on) {
        // All we advertise is our service's UUID
        [self.peripheralManager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]] }];
    }
    else {
        [self.peripheralManager stopAdvertising];
    }
}

BLE 处于开机状态并调用 startAdvertising。但是 BLE 中心永远无法发现它。

帖子更新:

根据mttrb的建议,我在开始广告时添加了“CBAdvertisementDataLocalNameKey”。但是我的服务仍然无法被大多数应用程序发现,包括来自应用商店的一些应用程序。唯一可以发现我的服务的应用是来自应用商店的一个名为“BLE 扫描仪”的应用。

我的问题是:这是否意味着我的应用程序正在作为外围设备工作?但是为什么我自己的代码无法发现服务呢?我应该如何调试它?

我在中央模式下的代码是这样的:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Start up the CBCentralManager
    _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}

- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
    if (central.state != CBCentralManagerStatePoweredOn) {
        return;
    }
    [self.centralManager scanForPeripheralsWithServices:nil options:nil];
}

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
......
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
    if (error) {
        NSLog(@"Error discovering services: %@", [error localizedDescription]);
        return;
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
    // Deal with errors (if any)
    if (error) {
        NSLog(@"Error discovering characteristics: %@", [error localizedDescription]);
        return;
    }
}

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    NSLog(@"Peripheral Disconnected");
    self.discoveredPeripheral = nil;
}

didDiscoverPeripheral 和 didDiscoverServices 永远不会被调用。有什么问题?任何想法?谢谢

4

5 回答 5

12

还有一个名为LightBlue的高质量免费应用程序,您可以使用它来测试您的代码。它应该能够接收所有在外围模式下广告的设备,如果您想确保您的设备正常工作,它甚至可以将自己变成一个广告外围设备。

于 2012-11-06T23:37:24.327 回答
4

我会尝试将startAdvertising:方法调用移动到您的peripheralManagerDidUpdateState:委托方法的末尾,看看是否有帮助。

我还将在您的方法调用中添加一个CBAdvertisementDataLocalNameKey键值对。startAdvertising:当广告没有名字时,我发现事情是不可靠的。

最后,我将投资App Store 中提供的BLExplr 应用程序,以帮助扫描您的外围设备。它消除了您的中心工作正常的假设。

于 2012-10-24T04:01:44.147 回答
3

这个 Git 中心项目还对 CBPeripheralManager API 有所了解。称为PeripheralModeTest。此行对于设置广告数据特别有用

 NSDictionary *advertisingData = @{CBAdvertisementDataLocalNameKey : @"Device Name", CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:CBUUIDGenericAccessProfileString]]};

虽然我在 Apple iOS Developer Library 中还看不到任何官方文档。更具体地说,有关设置广告重复周期的任何内容。

于 2013-01-08T10:43:14.657 回答
2

BTLE Transfer示例中有这段(奇数)代码,可能会造成一些麻烦:

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
    // Reject any where the value is above reasonable range
    if (RSSI.integerValue > -15) {
        return;
    }

    // Reject if the signal strength is too low to be close enough (Close is around -22dB)
    if (RSSI.integerValue < -35) {
        return;
    }

只需删除这两个 if 语句,因为它没有任何意义!

我在这里提供了一个简化版本,可用于测试从外围设备发送到中心的大量消息。

请注意,CBPeripheralManager该类最初是在 iOS 6.0 中引入的。

于 2014-02-12T09:57:10.653 回答
0

我不知道您实际测试过的BTLE Central Peripheral Transfer的女巫版本,但当前版本要求 iOS 6。

所以我建议测试与 iOS 5.1 的链接,看看它显示了哪些兼容性问题。

于 2013-06-26T13:11:49.130 回答