Подтвердить что ты не робот

Получите MAC-адрес периферийного устройства с низкой энергией bluetooth

В настоящее время я работаю над iOS-приложением, основанным на устройствах с низким энергопотреблением bluetooth. Чтобы получить уникальный идентификатор для сравнения полученных периферийных устройств, я должен получить MAC-адрес периферийных устройств.

Наблюдается, что свойство UUID периферийного устройства зависит от устройств iOS, а также для периферийного устройства для получения UUID, он должен будет подключиться к ведущему устройству хотя бы один раз. Поскольку я должен иметь дело с регистрацией, я не хочу устанавливать соединение. Когда я прошел через портал служб bluetooth, я обнаружил, что сама информация об устройстве является сервисом, который не может быть восстановлен, если не установлено соединение между главным устройством iOS и периферийным устройством с низким энергопотреблением Bluetooth.

Я обнаружил, что в Android мы получаем всю информацию об устройстве, включая его MAC-адрес (используя getAddress()), когда мы получаем ответ от устройства при самом сканировании.

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

Итак, есть ли способ в iOS, чтобы я мог получить MAC-адрес периферийного устройства с низкой энергией bluetooth без установления соединения?

Любая помощь будет принята с благодарностью.

4b9b3361

Ответ 1

Для получения этой информации нет открытого API.

Если это внутреннее или джейлбрейковое приложение, вы можете получить значение ключа kLockdownBluetoothAddressKey через liblockdown.dylib

Ответ 2

Свойство CBPeripheral identifier будет служить вашей цели, доступной из устройства, не подключенного к сети, в CBCentralManager didDiscoverПериферийный метод делегирования:

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

CBPeripheral *peripheral ...

NSUUID* serverId = [peripheral identifier];

У меня есть полдюжины устройств LE, с которыми я экспериментирую, включая несколько наборов одинаковых устройств. Я только что подтвердил, что на двух устройствах iOS идентификаторы для всех этих виджетов LE были разными, но для EACH iOS-устройства идентификатор для каждого виджета был сохранен во всех запусках приложений и даже при удалении и переустановке приложений. Я бы сказал, что это окончательно доказывает, что ОС хранит достаточно информации внутри, что для данного iThing вы сможете различать и переименовывать все периферийные устройства, с которыми сталкивается ваше приложение, без фактического подключения к ним. Также обратите внимание, что advertisementData, также доступный до подключения, полон полезной информации, такой как CBAdvertisementDataLocalNameKey, CBAdvertisementDataManufacturerDataKey, CBAdvertisementDataServiceUUIDsKey, CBAdvertisementDataSolicitedServiceUUIDsKey и другие, хотя никто не определен однозначно идентифицировать устройство как [периферийное идентификатор].

Я не пробовал делать резервное копирование и восстановление устройства, чтобы доказать, что UUID были сохранены, но я бы сделал ставку, и если это не так, то Apple подумает об ошибке.

Ответ 3

Низкоэнергетические периферийные устройства могут использовать функцию конфиденциальности, которая скрывает MAC-адрес, поэтому не обязательно даже получить адрес перед подключением или связью. Если вы каким-то образом получите MAC-адрес, который выходит по воздуху, вам нужно справиться с конфиденциальностью или у вас проблемы с совместимостью.

Apple использует UUID для абстрагирования этих функций конфиденциальности, поэтому пользователям не нужно беспокоиться о них.

Правильный способ сделать это, как вы писали, - либо добавить некоторые рекламные данные в рекламный пакет, либо использовать службу информации об устройстве.

Ответ 4

От имени обсуждения других профессионалов я нашел некоторые факты, которые говорят -

"iOS скрывает MAC-адрес устройства и генерирует UUID. UUID на iOS генерируется устройством iOS. Разные устройства iOS получат разные UUID для одного и того же периферийного устройства. MAC-адрес обычно основан на оборудовании. Если у нас обоих есть айфоны и мы сканируем одно и то же периферийное устройство, мы увидим разные UUID. iOS генерирует UUID на устройстве и скрывает MAC-адрес. Итог - iOS не позволяет вам получить MAC-адрес устройства, вместо этого выдает случайный UUID ".

Source - https://github.com/don/cordova-plugin-ble-central/issues/77

В соответствии с приведенным выше исследованием, я обнаружил, что пока нет такого уникального способа подключения к плате, у каждой платы есть MAC-адрес, который не меняется и легко доступен в (только) Android, в то время как iOS не позволяет получить доступ MAC-адрес периферийного устройства, однако iOS использует этот MAC-адрес для создания идентификатора периферийного устройства (UUID), который является уникальным только для (уникального) устройства. Идентификатор периферийного устройства для одной платы различен для разных устройств iPhone (но уникален для одного устройства).

Однако мы можем подключиться к плате, выполнив поиск с помощью UUID периферийной службы Bluetooth, но этот UUID службы одинаков для всех плат типа say- Adafruit Feather M0. Это означает, что приложение будет просматривать платы BLE того же типа ('Adafruit Feather M0') и подключаться к ЛЮБОМУ из них. Для того, чтобы подключиться к конкретному пользователю к определенной плате, кажется, что это пока невозможно из-за недоступности MAC и выдачи случайного UUID в iOS.

Ответ 5

Вы можете получить доступ к MAC-адресу без проблем в iOS 12. Чтобы получить MAC-адрес, выполните следующие действия.

  1. Разобрать данные, полученные устройством BLE, в строку.
extension Data{
func hexEncodedString() -> String {
        let hexDigits = Array("0123456789abcdef".utf16)
        var hexChars = [UTF16.CodeUnit]()
        hexChars.reserveCapacity(count * 2)

        for byte in self {
            let (index1, index2) = Int(byte).quotientAndRemainder(dividingBy: 16)
            hexChars.insert(hexDigits[index2], at: 0)
            hexChars.insert(hexDigits[index1], at: 0)
        }
        return String(utf16CodeUnits: hexChars, count: hexChars.count)
    }
}

  1. Добавьте разделитель ":" к адресу.
extension String {
    func separate(every stride: Int = 4, with separator: Character = " ") -> String {
        return String(enumerated().map { $0 > 0 && $0 % stride == 0 ? [separator, $1] : [$1]}.joined())
    }
}
  1. В didReadValueForCharacteristic (характеристика: CBCharacteritic) вы можете использовать предыдущие 2 функции для получения MAC-адреса.
func didReadValueForCharacteristic(_ characteristic: CBCharacteristic) {
if characteristic.uuid == BleDeviceProfile.MAC_ADDRESS, let mac_address = characteristic.value?.hexEncodedString().uppercased(){
            let macAddress = mac_address.separate(every: 2, with: ":")
            print("MAC_ADDRESS: \(macAddress)")
        }
}
  1. наслаждайтесь своим MAC-адресом: "MAC_ADDRESS: 00: 0A: 57: 4E: 86: F2"