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.

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?

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.

  • Samsung ble api no puede recibir notificación de múltiples características del GATT
  • Obtener UUIDs de G-Shock reloj bluetooth android
  • Android BLE: onCharacteristicChanged nunca se dispara
  • Cómo programaticamente forzar el descubrimiento de servicios de baja energía de bluetooth en Android sin usar caché
  • ¿Es posible utilizar un BLE habilitado para Android / iPhone como un faro BLE?
  • Android Bluetooth Código de baja energía compatible con API> = 21 Y API <21
  • Android BLE 4.3 onDescriptorWrite devuelve el estado 128 al habilitar la notificación de características
  • Nodificación de la señal de la señal de Bluetooth
  • Detectar si un dispositivo BLE puede conectarse en Android
  • El dispositivo Android BLE recibe resultados extremadamente irregulares
  • Android 6.0 Marsmallow BLE: Parámetros de conexión
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.