繁体   English   中英

将iOS 6设备作为BLE外围设备运行

[英]Run iOS 6 device as a BLE peripheral

众所周知,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的建议,我在startAdvertising时添加了“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。 可能有什么不对? 任何的想法? 谢谢

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

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

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

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

这个Git hub项目也为CBPeripheralManager API提供了一些启示。 称为PeripheralModeTest 此行对于设置广告数据特别有用

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

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

BTLE传输示例有这段(奇数)代码,可能会导致一些麻烦:

- (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中引入的。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM