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

Частные и общедоступные адреса в Bluetooth низкой энергии на Android

Устройство с низким энергопотреблением Bluetooth уникально идентифицировано по его адресу (в Android API они называют этот MAC-адрес и обозначают его как шестнадцатеричные значения, разделенные двоеточиями, например 11: aa: 22: bb: 33: cc).

Но для однозначного определения адреса BLE вам нужно знать, является ли он публичным или частным адресом. В сущности, 49 бит необходимы для идентификации адреса, а не 48.

Случайные адреса могут быть либо статическими случайными, неразрешимыми частными, либо разрешаемыми частями, и эти типы разделяются битовой диаграммой в двух наиболее значимых байтах (11, 00 и 10 соответственно).

Но я не вижу нигде, что вы можете отделить общедоступные и случайные адреса, просто взглянув на 48 бит в адресе.

Итак, как это работает в Android API? Как узнать, к какому устройству подключиться, когда они не знают, являются ли указанные вами адреса общедоступными или случайными?

В рассматриваемом API есть функция getRemoteDevice. В нем говорится:

Valid Bluetooth hardware addresses must be upper case, in a format such as
"00:11:22:33:AA:BB". The helper checkBluetoothAddress(String) is available
to validate a Bluetooth address.

A BluetoothDevice will always be returned for a valid hardware address,
even if this adapter has never seen that device.

Таким образом, вы даете функции 48 бит данных, и нет способа сказать, является ли адрес общедоступным или приватным. Это означает, что устройство не идентифицировано однозначно.

4b9b3361

Ответ 1

Поскольку у кого-то еще нет ответа, я начал тестировать сам.

Я попытался создать приложение, которое создает устройство из строкового представления адреса, и попытался настроить мое устройство с 48-битным адресом, чередующим публичный или частный бит, чтобы узнать, что делает стек Android.

private final BluetoothGattCallback leGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            Log.i("Fisken", "Gatt connected " + gatt.getDevice().getAddress() + " status " + status);
            if (status != BluetoothGatt.GATT_SUCCESS) {
                Log.w("Fisken", "Disconnect and close");
                gatt.disconnect();
                gatt.close();
            }
        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            Log.i("Fisken", "Gatt disconnected " + gatt.getDevice().getAddress() + " status " + status);
            if (status != BluetoothGatt.GATT_SUCCESS) {
                Log.w("Fisken", "Disconnect and close");
                gatt.disconnect();
            }
            gatt.close();
        }
    }
};

BluetoothAdapter mBluetoothAdapter = ((BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter();
BluetoothDevice d = mBluetoothAdapter.getRemoteDevice("FF:55:44:33:22:11");
d.connectGatt(this, false, leGattCallback);

С помощью этого кода, если я начну свое периферийное устройство BLE со случайным адресом, все будет работать так, как ожидалось. Однако, если я попробую запустить его с тем же адресом с установленным общим битом, logcat говорит "Gatt connected", но это просто не так. И я никогда не могу отключиться.

Обновление. Я сделал еще несколько тестов, чтобы понять это. Событие onConnectionStateChange, которое я получаю, - это просто время попытки подключения. Статус установлен на 133 (если я получаю STATE_CONNECTED) или 257 (если я получу STATE_DISCONNECTED), и я видел оба. В любом случае я должен (и теперь делать в примере кода) отменить попытку подключения и закрыть клиент.

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

Таким образом, это похоже на ошибку/и/или отсутствие функции в Android API. Это не позволяет вам подключиться к общедоступному адресу, не предварительно отсканировав его. Однако он работает для случайных адресов.

Ответ 2

Можно предположить, что адрес является общедоступным или случайным, хотя он не будет работать в каждом случае.

Как вы говорите выше, в случае случайного адреса оба MSB являются либо 00xx, 01xx, либо 11xx... поэтому, если это 10xx, то это общедоступный адрес (от компании, чей OUI начинается с 8,9, A или B)

Кроме того, количество зарегистрированных OUI очень ограничено по сравнению с существующим, поэтому путем поиска потенциального OUI в базе данных IEEE соответствующий результат, вероятно, будет означать общедоступный адрес.

Зарегистрированное количество OUI: ~ 20500, поэтому 0.12% из 2 ^ 24 бит и 0,48% из 2 ^ 22 бит.

Без базы данных IEEE можно полагаться на то, что первый LSB OUI всегда равен 0, а второй LSB почти всегда равен 0 (на самом деле он всегда должен быть 0, поскольку эти адреса используются повсеместно).

Кроме того, может использоваться другой статистический анализ: например, 60% OUI начинаются с 00. С другой стороны, не разрешимый частный адрес имеет только вероятность 1,66% начать с 00 (с равномерным случайным генератор).

Ответ 3

Я думаю, что ваши оригинальные "нужны 49 бит для различения публичных и случайных адресов" являются правильными. Я не могу найти ничего в кодировке общего адреса IEEE, который ограничивает MSB равным "10", который, если это правда, решит проблему.

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

Я добавлю: Из основной спецификации Vol 6 Часть B, раздел 1.3 Адреса устройств: Вызов MS = наиболее значимый

Static random address:          two MB bits of MS byte are 1 1 such that the MS byte is 11xxxxxx & with 0xC0
Non-resolvable private address: two MB bits of MS byte are 0 0 such that the MS byte is 00xxxxxx & with 0x00
Resolvable private address:     two MB bits of MS byte are 0 1 such that the MS byte is 01xxxxxx & with 0x40

Невозможно отличить общедоступный адрес от одного из вышеуказанных типов адресов, не имея также флаг типа адреса. Таким образом, потребность в "49-м" бите (дополнительный флаг). Только адрес не делает этого!

Ответ 4

Указывается ли публичный или закрытый рекламный адрес в заголовке рекламного сообщения. Установка типа адреса на уровне приложения для общего пользования означает, что уровень связи BLE будет передавать фактический адрес "MAC". Установка типа адреса в static/private resolvable указывает, что уровень связи BLE будет скремблировать адрес с помощью ключа разрешения идентификации (IRK).

Ответ 5

Вы можете различать общедоступные и частные адреса, просматривая два наиболее значимых бита. Адрес имеет длину 48 бит, а не 49. См. Спецификация основного Bluetooth v4.2, том 6, часть B, раздел 1.3.