Privado vs direcciones públicas en Bluetooth de baja energía en Android

Un dispositivo Bluetooth de baja energía está identificado de manera única por su dirección (en la API de Android llaman a ésta la dirección MAC y la denotan como valores hexagonales separados por p. Ej. 11: aa: 22: bb: 33: cc).

Pero para identificar de manera única una dirección BLE que necesita saber si se trata de una dirección pública o privada. En esencia, 49 bits son necesarios para identificar una dirección, no 48.

Las direcciones aleatorias pueden ser privadas estáticas, no solucionables privadas o solubles privadas y estos tipos están separados por un patrón de bits en los dos bytes más significativos (11, 00 y 10 respectivamente).

Pero no veo en ninguna parte que usted puede separar direcciones públicas y al azar apenas mirando los 48 pedacitos en la dirección.

Entonces, ¿cómo funciona esto en la API de Android? ¿Cómo saben a qué dispositivo conectarse cuando no saben si la dirección que ha especificado es pública o aleatoria?

La API en cuestión es, por ejemplo, la función getRemoteDevice . Dice:

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. 

Así que dar a la función 48 bits de datos y no hay manera de decir si la dirección es pública o privada. Esto significa que el dispositivo no está identificado de forma única.

5 Solutions collect form web for “Privado vs direcciones públicas en Bluetooth de baja energía en Android”

Puesto que nadie más parece tener una respuesta a ofrecer comencé a probar por mi cuenta.

He intentado hacer una aplicación que crea un dispositivo de una representación de cadena de una dirección y probé configurar mi dispositivo con la dirección de 48 bits alternando el bit público o privado para ver lo que hace la pila de 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); 

Con este código, si comienzo mi periférico BLE con una dirección aleatoria todo funciona como se esperaba. Sin embargo, si intento ejecutarlo con la misma dirección con el bit público establecido, logcat dice "Gatt conectado", pero eso no es cierto. Y nunca podré desconectarme.

Actualización : Hice algunas pruebas más para averiguar esto. El evento onConnectionStateChange que recibo es solo el intento de conexión que se agota. El estado se establece en 133 (si obtengo STATE_CONNECTED) o 257 (si obtengo un STATE_DISCONNECTED) y he visto ambos. En cualquier caso, debería (y ahora hacer en el código de ejemplo) cancelar el intento de conexión y cerrar el cliente.

También he descubierto que si hago un escaneo en primer lugar, para que el dispositivo que estoy tratando de conectar a se han visto recientemente y luego hacer una conexión basada únicamente en el dispositivo de dirección MAC, entonces puedo conectar a ambos al azar Y las direcciones públicas sin ningún problema.

Así que esto parece ser una característica de error / o falta en la API de Android. No le permite conectarse a una dirección pública sin haberla escaneado previamente. Sin embargo, funciona para direcciones aleatorias.

Es posible adivinar si la dirección es pública o aleatoria, aunque no funcionará en todos los casos.

Como usted dice arriba, en caso de una dirección aleatoria, ambos MSB son 00xx, 01xx o 11xx … así que si es 10xx, entonces es una dirección pública (de una empresa cuyo OUI comienza con 8,9, A o SEGUNDO)

Además, el número de OUI registrado es muy limitado en comparación con lo que existe, por lo que al buscar el potencial OUI en la base de datos IEEE, un resultado coincidente probablemente significará una dirección pública.

Cuota registrada de OUI: ~ 20500, por lo que 0,12% de 2 ^ 24 bits y 0,48% de 2 ^ 22 bits.

Sin la base de datos IEEE, es posible confiar en el hecho de que el primer LSB de un OUI es siempre 0, y el segundo LSB es casi siempre 0 (en realidad, siempre debe ser 0 como estas direcciones son universalmente administrados).

Por otra parte, una dirección privada no resuelta, tiene sólo una probabilidad de 1.66% para empezar con 00 (con generador aleatorio uniforme).

Creo que su original "necesita 49 bits para distinguir entre direcciones públicas y aleatorias" es correcto. No puedo encontrar nada en la codificación de una dirección pública IEEE que restringe el MSB a ser '10' que, si es cierto, resolvería el problema.

Así que lo único que se puede usar es el ajuste de bit de "dirección aleatoria" en los anuncios de la configuración periférica o bit equivalente en el paquete de iniciación de conexión de la central. Si estos bits no están configurados, entonces la dirección que el citado punto extremo expone es pública.

Si la dirección de publicidad es pública o privada se establece en el encabezado del mensaje publicitario. La configuración del tipo de dirección en la capa de aplicación en público significa que la capa de enlace BLE transmitirá la dirección "MAC" actual. El ajuste del tipo de dirección a static / private resoluble, indica que la capa de enlace BLE codificará la dirección con una clave de resolución de identidad (IRK).

Puede diferenciar entre direcciones públicas y privadas mirando los 2 bits más significativos. Una dirección tiene 48 bits de longitud, no 49. Consulte Core Bluetooth Specification v4.2, Vol. 6, Parte B, Sección 1.3.

  • ¿Es posible conectar el dispositivo Android Wear con otro dispositivo BLE directamente sin interacción del dispositivo telefónico?
  • ¿Cómo mejorar la medición de la distancia Bluetooth mediante RSSI?
  • Reemplazo de startLeScan a api actual
  • Cómo obtener datos de un dispositivo Bluetooth LE
  • Android BLE notificaciones pérdida de paquetes
  • Análisis pasivo de Android BLE
  • ¿Es posible conectar iOS y dispositivos Android con Bluetooth?
  • Android BLE Gatt Característica WRITE_TYPE_NO_RESPONSE no funciona
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.