Как сканировать только маяки с CoreBluetooth


Я использовал эту функцию для сканирования BLE вокруг меня, но я получаю слишком много сигналов. Я бы хотел работать только с сигналами от маяков.

func centralManagerDidUpdateState(_ central: CBCentralManager) {
    centralManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey : NSNumber(value: true)])
}

Я использовал LightBlue и обнаружил, что мой маяк имеет 5 служб: 180A, FFA0, FFB0, FFF0 и 180F.

Затем я попробовал этот код, но никаких периферийных устройств с этим сервисом не нашел.

let serviceUUIDs = [CBUUID(string: "FFA0")]

func centralManagerDidUpdateState(_ central: CBCentralManager) {
    centralManager.scanForPeripherals(withServices: serviceUUIDs, options: [CBCentralManagerScanOptionAllowDuplicatesKey : NSNumber(value: true)])
}

И метод didDiscover никогда не вызывался

func centralManager(_ central: CBCentralManager,
                    didDiscover peripheral: CBPeripheral,
                    advertisementData: [String : Any],
                    rssi: NSNumber)
{
    if peripheral.name == "MY_BEACON_NAME" {
        print("peripheral: \(peripheral)")
        print("rssi = \(rssi)")
    }
}

Что я делаю не так?

P. S. Я не могу использовать для этого CoreLocation проект, только CoreBluetooth.

1   2  

1 ответ:

В зависимости от того, какой формат маяка рекламирует ваш аппаратный Маяк, его может быть невозможно обнаружить с помощью CoreBluetooth. CoreBluetooth может обнаруживать форматы Eddystone и AltBeacon, но не может обнаруживать формат iBeacon.

Несколько моментов, чтобы понять:

  1. Форматы Маяк не обязательно включают в себя услуги ГАТТ идентификатор UUID, который является то, что вы фильтруете, когда вы используете строку кода centralManager.scanForPeripherals(withServices: serviceUUIDs .... В то время как реклама Eddystone действительно включает сервис UUID, iBeacon и AltBeacon не делают этого, потому что они представляют собой другой вид рекламы BLE, называемый рекламой производителя. Только объявления ГАТТ имеют сервисные UUID.

  2. Форматы Eddystone используют сервис FEAA UUID, и Вы можете использовать метод, который вы описываете, чтобы фильтровать для этого типа маяка.

  3. Вы можете обнаружить рекламу AltBeacon только без фильтра serviceUUID, потому что у него его нет.

  4. Вы можете никогда не обнаруживайте iBeacon с CoreBluetooth, потому что у Apple есть специальные фильтры кода, которые блокируют его API от получения этих рекламных объявлений. У вас нет выбора, кроме как использовать CoreLocation для обнаружения iBeacon на iOS.

  5. Многие производители оборудования для маяков также включают некоторые дополнительные службы GATT, которые имеют свои собственные UUID служб. Эти службы выполняют такие функции, как настройка или добавление действий. Но они не имеют ничего общего с функциональностью маяка, и нет никакого способа узнать, когда (если когда-либо) эти сервисные UUID рекламируются, и что это означает, если они есть. Эти UUID будут абсолютно отличаться от одного производителя маяка к другому. сервисные UUID, обнаруживаемые LightBlue, скорее всего, являются дополнительными сервисами, и по этой причине они просто не полезны для решения этой проблемы.

Итог: нет простого способа использовать CoreBluetooth для фильтрации только тех маяков, которые вы хотите. Ваш лучший выбор-это напишите свою собственную программу фильтрации поверх CoreBluetooth и просто игнорируйте пакеты, о которых вы не заботитесь.