tutorial things studio low example ble android android-sensors bluetooth-lowenergy android-bluetooth

things - Android 4.3: BLE: comportamiento de filtrado de startLeScan()



bluetooth low energy android studio tutorial (5)

Con Android 4.3 y 4.4 hasta ahora, parece ser un desastre: algunos dispositivos invocan onLeScan (dispositivo BluetoothDevice, int rssi, byte [] scanRecord) varias veces para un dispositivo en una exploración, otros no. No hay forma de configurar el filtrado como en iOS (ver respuesta de Arkadiusz Konior). Por lo tanto, ahora comienzo una lista, porque no puedo hacerles a mis usuarios una pregunta sobre su dispositivo.

Sin embargo, reiniciar el análisis tampoco es un problema en los dispositivos "sin filtrar". Entonces, reinicio el escaneo en todos los dispositivos ahora.

No filtrando (Llamando continuamente aLeScan ())

  • Samsung Galaxy S4 con 4.2.2 usando Samsung BLE sdk (yo era el propietario de ese dispositivo)
  • Nexus 5 con 4.4 (agregado por [vegarwe]. El dispositivo proporcionará registros de escaneo continuamente para los dispositivos cercanos mientras se escanea)
  • Samsung Galaxy S3 con 4.3 (JSS15J.I9300XXUGMK6, estaba probando en ese dispositivo)
  • Samsung Galaxy S4 con 4.3 y 4.4.2 con Android SDK (agregado por arnaud.b , sin compilación)
  • HTC One con 4.4.2 (agregado por arnaud.b , no se proporciona el número de compilación)

Dispositivos de filtrado (se aplica a la norma)

  • Nexus 4 con 4.3, 4.4 (soy dueño de ese dispositivo)
  • Nexus 7 2013 4G con 4.4.2 (KOT49H, estaba probando en ese dispositivo)
  • Samsung Galaxy S4 mini con 4.2.2 (estaba probando en este dispositivo)
  • Motorola Moto X (agregado por el user1603602 , no se proporciona información sobre la versión de Android)
  • Motorola Moto G con 4.3 (falcon_umts, Mi dispositivo de prueba)
  • Sony Xperia Tablet Z Wifi con Android 4.3 (compilación 10.4.B.0.577, modelo SGP311, mi dispositivo de prueba)
  • OnePlus One con 5.0.1 y 5.1.1 (Cyanogen 12.1)

Comportamiento de filtrado desconocido (ayude a asociar el dispositivo a un grupo determinado)

  • Nexus 7 2013 (Se reportan diferentes comportamientos como here . Pero he leído más informes que pertenecen al primer grupo).
  • Otros dispositivos de SAMSUNG, HTC, Motorola, ...,

Estoy trabajando en un dispositivo sensor BluetoothLE, para el cual necesito formar una transmisión de datos de uno a muchos. Según la especificación, los periféricos solo pueden tener un solo maestro, y debido a las limitaciones del chip y la pila que estoy diseñando, un maestro solo puede tener tres esclavos. Por lo que entiendo, Android no puede convertirse en un esclavo BLE, por lo que tener mi dispositivo como maestro no es una opción.

Tanto la especificación BT4 como la documentación del fabricante hablan de otro modo de operación, denominado modo de transmisión. En el modo de transmisión, nunca se establece una conexión y los datos de la aplicación se transmiten como parte del paquete de publicidad. Esto se ajustará exactamente a mis necesidades, ya que muchos teléfonos Android / iOS pueden escanear simultáneamente cada paquete. Un paquete de publicidad se transmite varias veces en ráfagas, por lo que sospecho que la recepción de datos es en su mayoría confiable. Si un paquete se pierde aquí y allá, puede ser tolerado.

Donde esto se pone interesante, es que quiero que estos paquetes lleven datos de sensores en vivo, que se actualizan a una velocidad de 10-20Hz. De los ejemplos que he encontrado en la web, BLE en este modo se usa principalmente para implementaciones de tipo "iBeacon", donde están transmitiendo datos estáticos. No puedo encontrar información sobre cómo se filtran los paquetes de publicidad dentro de la pila de Android. Puede ser que devuelvan un resultado por dirección de hardware de Bluetooth, o podría ser la combinación única de dirección y datos. La segunda opción funcionaría para esta aplicación. Si al iniciar y detener el escaneo se restablece el filtro, también puedo hacer que algo funcione.

La documentación de Android no menciona nada sobre cómo funciona el filtrado de dispositivos en el método de escaneo. He podido encontrar una publicación en la red que intenta resolver este mismo problema, que tiene una respuesta no resuelta: BLE: descubrimiento múltiple del mismo periférico durante la exploración . En iOS, mi colega me informa que hay un parámetro que se puede pasar a la función de escaneo que lo hace posible.

Intenté rastrear el código desde la llamada startLeScan () en la fuente de Android, pero el código es bastante complejo, y el uso de la abstracción ha dificultado la identificación de la implementación del objeto que lo contiene. Lo más lejos que he llegado es a un objeto IBluetoothGatt devuelto por el método de la clase BluetoothManagerService getBluetoothGatt (). Este objeto recibe la solicitud para comenzar a escanear. Se está creando una instancia alrededor de la línea 790 de BluetoothManagerService.java en la revisión actual en vivo en github. El objeto se emite a partir del resultado de un mensaje, por lo que sospecho que tal vez el resultado sea específico del teléfono / controlador. Está más allá de mi experiencia poder seguir rastreando.

Otra pregunta que me gustaría resolver es qué tan rápido se puede activar y desactivar el escaneo. La exploración es una operación que consume mucha energía, pero la transmisión de datos se realizará periódicamente en un temporizador de tiempo real bastante preciso. Como resultado, sería una gran optimización si el escaneo se puede activar y desactivar, de manera que la emisión y el escaneo estén sincronizados, con el escáner apagado el otro 90% del tiempo. Esto probablemente tendrá que ser probado experimentalmente.

Todavía estoy haciendo una investigación de viabilidad para ver si esto es posible para nuestro accesorio para Android. Mi teléfono actual aún no puede ejecutar la versión 4.3, por lo que no tengo forma de probar / hackear esto experimentalmente.


El texto en las páginas 2535-2536 en la especificación de Bluetooth (Core_v4.1.pdf) sobre informes publicitarios duplicados es algo poco claro. Sin embargo, el texto en la página 1258 es claro. Especifica un parámetro Filter_Duplicates para el comando HCI_LE_Set_Scan_Enable. En la versión de Android 4.4 (Kitkat), este parámetro es 0x00 (Duplicado filtrado deshabilitado).

Hay una forma sencilla de averiguar si se realiza algún filtrado en el chip Bluetooth desde las versiones de Android 4.4 (Kitkat). Convierta el teléfono en un teléfono de desarrollador, ingrese las opciones de desarrollador y marque “Habilitar el registro snoop de Bluetooth HCI”. Luego, apague y encienda el Bluetooth una vez para hacer que los ajustes sean importantes. A partir de ahora, todos los paquetes HCI entre el procesador de la aplicación y el chip Bluetooth se almacenarán en el teléfono en un archivo que se extrae mediante el almacenamiento de adb pull / emulated / legacy / btsnoop_hci.log. Este no es un archivo de texto y necesita un programa de http://www.fte.com/products/default.aspx o wireshark para ver btsnoop_hci.log. Para Wirehark necesita una versión bastante reciente, ya que las versiones anteriores no son compatibles con BLE. Mi experiencia es que nunca hay ningún filtro en el chip Bluetooth, es decir, se envía el "Evento de Informe de Publicidad LE" del Evento HCI para cada ADV_IND y ADV_NONCONN_IND que recibe el chip Bluetooth. Esto se aplica a los teléfonos con chips Bluetooth Qualcomm / Atheros WCN 3680 y Broadcom BCM 4339.

Corrección: la ruta a btsnoop_hci.log puede ser diferente según el fabricante del teléfono. Puede encontrar la ruta correcta por adb shell cat, etc / bluetooth / bt_stack.conf | grep BtSnoopFileName


En iOS, este indicador se denomina CBCentralManagerScanOptionAllowDuplicatesKey . Pasarlo a la función de escaneo causa una notificación para cada paquete de publicidad. No pude encontrar una bandera similar en Android.


Estoy desarrollando la aplicación para Android 4.3 (Nexus 4 y 7) usando BLE y, desde mis observaciones, el escaneo devuelve el mismo dispositivo varias veces si no se envió una SOLICITUD DE EXPLORACIÓN al periférico.

El dispositivo puede anunciarse de 2 formas: pasivo y activo. En modo pasivo, el dispositivo periférico está publicitando todos sus datos y no escucha después de enviar paquetes periódicos. Es solo enviar, dormir, enviar, dormir ... En el modo activo, el sensor también anuncia, pero el mensaje es lo más corto posible. Después de enviarlo cambia a escuchar por un tiempo muy corto. Cuando el escaneado detecta el mensaje corto, envía inmediatamente el comando SCAN REQUEST al periférico y obtiene respuesta con más detalles. Por lo que puedo ver, Android no envía SOLICITUD DE ESCANEADO varias veces durante un escaneo.

Supongamos que tenemos 2 dispositivos en rango. Uno es el sensor de temperatura nRF (publicidad pasiva) de fe Nordic y otro dispositivo conectable. He recibido la siguiente respuesta de escaneo:

11-10 21:32:54.281: D/BluetoothAdapter(13468): startLeScan(): null 11-10 21:32:54.281: D/BluetoothAdapter(13468): onClientRegistered() - status=0 clientIf=4 11-10 21:32:54.321: D/BluetoothAdapter(13468): onScanResult() - Device=CD:61:1A:A8:BC:BE RSSI=-94 11-10 21:32:55.122: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-61 11-10 21:32:56.414: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-62 11-10 21:32:57.715: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-61 11-10 21:32:59.016: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-63 11-10 21:33:01.609: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-63 11-10 21:33:02.901: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-63 11-10 21:33:04.212: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-62 11-10 21:33:04.282: D/BluetoothAdapter(13468): stopLeScan()

Como puede ver, el dispositivo conectable apareció solo una vez y el otro 7 veces.

Otra pregunta que me gustaría resolver es qué tan rápido se puede activar y desactivar el escaneo. La exploración es una operación que consume mucha energía, pero la transmisión de datos se realizará periódicamente en un temporizador de tiempo real bastante preciso. Como resultado, sería una gran optimización si el escaneo se puede activar y desactivar, de manera que la emisión y el escaneo estén sincronizados, con el escáner apagado el otro 90% del tiempo. Esto probablemente tendrá que ser probado experimentalmente.

La frecuencia de escaneo depende del dispositivo. Además, la publicidad generalmente se realiza en 3 canales: 37, 38 y 39 para aumentar la probabilidad de ser encontrado. Sin embargo, esto podría ser una buena idea para obtener paquetes de publicidad de dispositivos ''activos'' varias veces.


La especificación de bluetooth real dice:

No se requiere que los informes publicitarios duplicados se envíen al Anfitrión. Un informe publicitario duplicado es un informe publicitario para la misma dirección del dispositivo mientras la capa de enlace permanece en el estado de escaneo. Los datos publicitarios pueden cambiar; los datos publicitarios o los datos de respuesta de escaneo no se consideran significativos al determinar informes publicitarios duplicados.

De acuerdo con la especificación, esto se aplica dentro de un período de exploración, lo que sugiere que la forma correcta de evitarlo es detener y reiniciar la exploración cada vez que reciba un anuncio.

Según mi experiencia con BLE, parece que enviar datos variables en anuncios no es una buena idea. Casi todo supone que los datos de los anuncios no cambian. Si realmente desea enviar datos variables (por ejemplo, lecturas de termómetros), es mucho mejor conectarse al dispositivo y hacerlo a través de una característica. Es más confiable y usa mucho menos energía. El inconveniente es que solo se puede conectar a 8 dispositivos a la vez.

Los anuncios están destinados a detectar la presencia de dispositivos e identificarlos.