Comunicación robusta con múltiples dispositivos BLE simultáneamente en Android
Aunque no documentado, la sabiduría convencional usando el apis BLE de Android es que ciertas operaciones como lectura y escritura de características y descriptores deben hacerse uno a la vez (aunque algunos dispositivos son más indulgentes que otros). Sin embargo, no estoy claro si esta política debe aplicarse sólo a una sola conexión, oa través de todas las conexiones activas.
He oído que es mejor iniciar conexiones a dispositivos uno a la vez. Éste podría ser un ejemplo de operaciones (connect / connectGatt) que deberían ejecutarse en serie entre todos los dispositivos.
- Cómo forzar Bluetooth LE "Just Works" Emparejamiento en Android
- Creación de servicios de fondo para Bluetooth de baja energía en Android
- Bluetooth Low Energy Service Discovery con Android 4.3 en Nexus 4
- Seguridad de emparejamiento BLE
- Android BLE: onCharacteristicRead () parece estar bloqueado por subprocesos
Pero para otras operaciones, como las características de lectura y escritura, ¿es suficiente si cada conexión ejecuta operaciones en serie, o necesito alguna cola de operación global compartida entre todos los dispositivos para que entre todos los dispositivos, sólo se esté ejecutando una operación?
- Android BLE notificaciones pérdida de paquetes
- Android lolipop java.lang.SecurityException: Ni el usuario ni el proceso actual tiene android.permission.BLUETOOTH_PRIVILEGED
- Problema de conectividad de Android BLE Re
- Cambio de tiempo de gatt de bajo consumo de energía de bluetooth o descarga de flujo de lectura para detectar el evento de desconexión más rápido
- Android BLE: no se puede escribir una característica (no PROPERTY_WRITE)
- Android Bluetooth baja energía - iBeacon
- Descubrimiento del servicio BLE de Android (BluetoothGatt # discoverServices ()) y Low Energy vs BR / EDR
- Emparejamiento con un dispositivo Bluetooth de baja energía en Android
En Android, por objeto BluetoothGatt sólo debe ejecutar una operación a la vez (petición mtu, descubrir servicios, leer / escribir característica / descriptor) de lo contrario las cosas saldrán mal. Tienes que esperar hasta que se llame la llamada correspondiente hasta que puedas ejecutar la siguiente operación.
En cuanto a tener conexiones pendientes a varios dispositivos al mismo tiempo, si usa autoConnect = true, entonces no hay problema, pero si utiliza autoConnect = false entonces la pila Bluetooth de Android solo intentará conectarse a un dispositivo a la vez, las solicitudes de conexión si hay más de una pendiente. Hay un error en particular en el que no se puede cancelar una conexión pendiente que todavía está en la cola (cuando se llama .disconnect () o .close ()) sin embargo, que se ha arreglado recientemente en Android.
Tenga en cuenta que también hay un número máximo de conexiones / conexiones pendientes / gatt objetos para los que el comportamiento es completamente indocumentado lo que sucede cuando se superan estos límites. En los mejores casos simplemente obtener una devolución de llamada con el estado de error, pero en algunos casos he visto que la pila de bluetooth androide se queda atascado en un bucle sin fin en el que en cada iteración dice el controlador bluetooth para conectarse a un dispositivo, pero el controlador envía de vuelta las conexiones máximas del código de error alcanzadas.
Aunque no puedo hablar de la capa superior, puedo relacionarme con lo que sucederá en el nivel de hardware más bajo y que podría proporcionar algunas ideas para su diseño.
Cualquiera que sea la pila en la capa superior haciendo, al final la operación tiene que ser manejado por el chip transceptor.
BLE está operando sobre 40 bandas de canal en las cuales 3 se utilizan para la difusión y otros para la transmisión de datos. Esto se hace para poder tener multitud de dispositivos comunicándose juntos limitando la colisión por estar en otras bandas de frecuencia.
Estas bandas se seleccionan en función de la que tiene el menor ruido (o tráfico).
El propio transceptor sólo es capaz de comunicarse (hablar y escuchar) en una banda a la vez y tiene que cambiar entre las bandas para llegar a otros dispositivos. Esto se hace por un calendario muy ajustado de la comunicación.
Otro hecho es que un transceptor inalámbrico es básicamente algún tipo de comunicación semidúplex con detección de colisión, no puede enviar y escuchar al mismo tiempo, ni tampoco dos dispositivos emiten al mismo tiempo en la misma banda. Por lo tanto, es por diseño (y leyes de la naturaleza) en serie o secuencial.
Si implementa algún tipo de cola operativa o implementación de subprocesos, al final todo tendrá que ser tratado en serie / secuencialmente por el transceptor.
Si accede a él por diferentes hilos, el transceptor puede tener que saltar todo el tiempo entre los canales o tal vez se confunde si no se maneja bien en el nivel superior.
La única buena razón que puedo ver para tratar que en el hilo sería que el tiempo de procesamiento del transceptor a ser significativamente inferior a la pila superior que tiene que ejecutar, y que se aprovecharía de procesador de núcleo múltiple.
Pero de lo contrario, a menos que la necesidad de software muy específica o la arquitectura, no creo que tendrá ganancia significativa de tener una implementación diferente de serie y yo también hablar con los esclavos uno por uno en lugar de todo al mismo tiempo por las consideraciones explicadas anteriormente.
BLE está diseñado para ser asincrónico y dirigido por eventos. Puede enviar los comandos como quiera y obtendrá las respuestas en ningún orden en particular. Si envías un comando y esperas que el siguiente paquete sea la respuesta, vas a tener problemas.
Dicho esto, no estoy seguro de cómo la biblioteca de Android se estructura en torno a esto.
- Google Map V2 cómo configurar ZoomToSpan?
- Eclipse Android Debugger – ¿Dónde en mi código he causado la excepción?