0

Я создал два приложения для iOS; один периферийный элемент Bluetooth LE, который рекламирует услугу, и один центр Bluetooth LE, который сканирует рекламируемый сервис. Периферийное устройство работает на моем iPhone5, а центральный работает на моем iPad Mini. Сначала я установил центральную задачу для сканирования конкретной рекламируемой услуги, но позже изменил ее для прослушивания любой службы. В любом случае приложение iPad Mini, действующее как центральный, никогда не обнаруживает рекламируемого сервиса. Я не уверен, что это проблема с тем, как я настраиваю периферийного менеджера для рекламы, или если это проблема с тем, как я настраиваю центральный диспетчер для сканирования или проблему конфигурации устройства. Пожалуйста, предложите предложения или тесты, которые я могу выполнить, чтобы это работало.Не удалось обнаружить Bluetooth LE Service Реклама в iOS

Ниже приведен соответствующий код приложения iPhone5s действует как периферический:

CBPeripheralManager *peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil options:nil]; 

CBUUID *immediateAlertServiceUUID = [CBUUID UUIDWithString: IMMEDIATE_ALERT_SERVICE_UUID]; 
CBUUID *alertLevelCharacteristicUUID = [CBUUID UUIDWithString: ALERT_LEVEL_CHARACTERISTIC_UUID]; 
CBUUID *myCustomCharacteristicUUID = [CBUUID UUIDWithString: MY_CUSTOM_CHARACTERISTIC_UUID]; 

alertLevelCharacteristic = 
[[CBMutableCharacteristic alloc] initWithType:alertLevelCharacteristicUUID 
            properties:CBCharacteristicPropertyRead 
             value: nil permissions:CBAttributePermissionsReadable]; 
myCustomCharacteristic = 
[[CBMutableCharacteristic alloc] initWithType:myCustomCharacteristicUUID 
            properties:CBCharacteristicPropertyRead 
             value: nil permissions:CBAttributePermissionsReadable]; 

NSArray *myCharacteristics = @[alertLevelCharacteristic, myCustomCharacteristic]; 

// Now setup the service 
myService = [[CBMutableService alloc] initWithType:immediateAlertServiceUUID primary:YES]; 

// Finally, associate the characteristic with the service. This is an array of characteristics 
myService.characteristics = myCharacteristics; 

[peripheralManager addService:myService]; 

... wait for user to push button to start advertising ... 

// Start Advertising 
[peripheralManager startAdvertising:@{ CBAdvertisementDataLocalNameKey : @"My Service", 
             CBAdvertisementDataServiceUUIDsKey : @[myService.UUID] }]; 

И вот необходимые методы делегата. ПРИМЕЧАНИЕ: метод делегирования foreignalManagerDidUpdateState срабатывает и указывает, что «оборудование BLE на базе ядра BBS включено и готово» (то же самое верно на центральной стороне). Метод делегирования: периферийный диспетчер: didAddService: ошибка срабатывает без ошибок (см. Вывод ниже). И метод делегирования hyperalManagerDidStartAdvertising: ошибка срабатывает без ошибок). Вот информация служб распечатана из didAddService:

<CBMutableService: 0x17008efb0 Primary = YES, UUID = 1802, Included Services = (null), Characteristics = (
"<CBMutableCharacteristic: 0x1702c1500 UUID = 2A06, Value = (null), Properties = 0x2, Permissions = 0x1, Descriptors = (null), SubscribedCentrals = (\n)>", 
"<CBMutableCharacteristic: 0x1702c15e0 UUID = 66E613B5-7225-42C6-A9C2-11FADAE62899, Value = (null), Properties = 0x2, Permissions = 0x1, Descriptors = (null), SubscribedCentrals = (\n)>")> 

CBPeripheralManager Делегатой метода (извините за весь код, просто пытаюсь быть полными.):

- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { 

// Determine the state of the peripheral 
if ([peripheral state] == CBPeripheralManagerStatePoweredOff) { 
    NSLog(@"CoreBluetooth BLE hardware is powered off"); 
} 
else if ([peripheral state] == CBPeripheralManagerStatePoweredOn) { 
    NSLog(@"CoreBluetooth BLE hardware is powered on and ready"); 
} 
else if ([peripheral state] == CBPeripheralManagerStateUnauthorized) { 
    NSLog(@"CoreBluetooth BLE state is unauthorized"); 
} 
else if ([peripheral state] == CBPeripheralManagerStateUnknown) { 
    NSLog(@"CoreBluetooth BLE state is unknown"); 
} 
else if ([peripheral state] == CBPeripheralManagerStateUnsupported) { 
    NSLog(@"CoreBluetooth BLE hardware is unsupported on this platform"); 
} 
} 

- (void)peripheralManager:(CBPeripheralManager *)peripheral 
     didAddService:(CBService *)service 
       error:(NSError *)error { 

if (error) { 
    NSLog(@"Error publishing service: %@", [error localizedDescription]); 

    return; 
} 
else { 
    NSLog(@"Hurray! Your Service has been successfully published as: %@", service); 
} 
} 

- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral 
            error:(NSError *)error { 

if (error == nil) { 
    NSLog(@"Your service is now advertising"); 
} 
else { 
    NSLog(@"In peripheralManagerDidStartAdvertising: Your service advertising failed with error: %@", error); 
} 

} 

А вот соответствующий центральный код, который работает на iPad Mini:

// Scan for all available CoreBluetooth LE devices 
NSArray *services = @[[CBUUID UUIDWithString:IMMEDIATE_ALERT_SERVICE_UUID]]; 

CBCentralManager *centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; 

//[centralManager scanForPeripheralsWithServices:services options:nil]; 
[centralManager scanForPeripheralsWithServices:nil options:nil]; 
self.centralManager = centralManager; 

И вот один из методов Центрального делегата. За исключением centralManagerDidUpdateState: ни один из методов делегирования не срабатывает.

// CBPeripheralDelegate - Invoked when you discover the peripheral's available services. 
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error 
{ 
    NSLog(@"Did Discover Services"); 
    for (CBService *service in peripheral.services) { 
     [peripheral discoverCharacteristics:nil forService:service]; 
    } 
} 

// 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 
{ 
NSLog(@"Did Discover Peripheral"); 
NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey]; 
if (![localName isEqual:@"My Service"]) { 
    // We found the Device 
    [self.centralManager stopScan]; 
    self.myPeripheral = peripheral; 
    peripheral.delegate = self; 
    [self.centralManager connectPeripheral:peripheral options:nil]; 
} 
} 

В заключение я задаюсь вопросом, работает ли BLE даже на моих устройствах. Я загрузил пару различных приложений iBeacon на iPhone и iPad Mini, чтобы узнать, могу ли я получить два устройства для распознавания iBeacons (один передает, один получает), но они также не обнаружили iBeacons. Я также пробовал с двумя iPhone'ами. Я также отключил Bluetooth. Я также попытался отключить/выключить устройства. Оба устройства работают на переднем плане. Еще не повезло. Пожалуйста помоги.

+1

Когда вы сканируете? Неясно, ожидаете ли вы [состояние периферийного диспетчера] «нормально». Кроме того, видит ли LightBlue ваши устройства? Есть ли 2 приложения с двумя устройствами Ligthblue, он работает? – Larme

+0

@ Larme Я пробовал сначала запустить Central и сначала запустить Peripheral. Ни один из подходов не работает. Вопрос: как только сканирование запускается, постоянно ли оно сканируется (т.имеет значение, что начинается сначала)? Я не пробовал LightBlue. Я попробую это сейчас. – JeffB6688

+0

@ Larme Хорошо, я попробовал LightBlue. Он обнаруживает, что услуга рекламируется с моего iPhone. Таким образом, это предполагает, что существует проблема с центральным сканированием. Вы видите что-то не так с кодом, который у меня есть в Центре, для сканирования и обнаружения службы? – JeffB6688

ответ

1

Я сцепить все комментарии здесь:

Использование приложений, как LightBlue или BLE Utility может помочь вам найти, если ваш вопрос находится на периферии или центральной, так как вы разрабатываете обе стороны самостоятельно.

Перед тем, как искать CBServices, вам необходимо подключиться к CBPeripheral. Метод, который вы показывали перед рукой, и кажется, что это не было очевидно.

Кроме того, перед началом сканирования с помощью CBCentralManager вы должны проверить его state, и это должно быть CBPeripheralManagerStatePoweredOn.

Смежные вопросы