Запустите устройство iOS 6 как периферийное устройство BLE - программирование
Подтвердить что ты не робот

Запустите устройство iOS 6 как периферийное устройство BLE

Как известно, iOS 6 поддерживает запущенные устройства (iPhone 4 и выше и новый iPad) как периферийное устройство BLE. В WWDC 2012 Сессия 705 есть демо-версия "Advanced core bluetooth". Я попросил у Apple исходный код. Они отправили мне модифицированную версию исходного кода (BTLE_Transfer_Draft). Тогда I:

  • Запустите приложение на 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 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 и didDiscover никогда не вызываются. Что может быть неправильным? Есть идеи? Спасибо

4b9b3361

Ответ 1

Существует также бесплатное приложение высокого качества LightBlue, которое вы можете использовать для тестирования своего кода. Он должен иметь возможность отображать рекламу всех устройств в периферийном режиме и даже превращаться в рекламную периферию, если вы хотите убедиться, что ваше устройство работает правильно.

Ответ 2

Я бы попытался переместить метод метода startAdvertising: и в конце вашего метода делегата peripheralManagerDidUpdateState: и посмотреть, помогает ли это.

Я бы также добавил пару ключ-значение CBAdvertisementDataLocalNameKey к вызову метода startAdvertising:. Я обнаружил, что вещи были ненадежными, когда у рекламы не было имени.

Наконец, я бы инвестировал в приложение BLExplr, доступное в App Store, чтобы помочь в сканировании вашего периферийного устройства. Это устраняет предположение, что ваш центральный процессор работает правильно.

Ответ 3

Этот проект Git hub также проливает свет на API CBPeripheralManager. Вызывается PeripheralModeTest. Эта строка особенно полезна для настройки рекламных данных.

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

Хотя я еще не вижу официальной документации в библиотеке разработчиков Apple iOS. Более конкретно, о настройке периода повторения рекламы.

Ответ 4

В примере 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.

Ответ 5

Я не знаю версию wah BTLE Central Peripheral Transfer, которую вы действительно протестировали, но текущая версия имеет iOS 6 как требование.

Поэтому я бы предложил протестировать связь с iOS 5.1, чтобы узнать, какие проблемы совместимости он показывает.