samsung - Android 6.0 Marsmallow BLE: parámetros de conexión
marshmallow android (4)
La gestión de parámetros de conexión Bluetooth Low Energy parece haber cambiado en Android 6.
Tengo un dispositivo periférico BLE que necesita usar algunos parámetros de conexión específicos (notablemente, el intervalo de conexión), y quiero usar el intervalo mínimo de conexión permitido por la especificación BLE (es decir, 7,5ms).
El Android SDK no permite elegirlo desde el lado de BLE GAP Central (el teléfono inteligente), por lo que la forma correcta de hacerlo es hacer que mi dispositivo GAP Peripheral envíe una L2CAP Connection Parameter Update Request
después de que se haya realizado la conexión GAP.
Los parámetros que solicito son:
- intervalo de conn min: 7,5 ms
- conn interval max: 7,5ms
- Latencia esclava: 0
- tiempo de espera de supervisión: 2000 ms
Esto funcionó como esperaba con todos los dispositivos Android que he estado probando, de 4.3 a 5.x: después de enviar la L2CAP Connection Parameter Update Request
, mi dispositivo recibe una L2CAP Connection Parameter Update Response
con 0x0000 (aceptado), seguido de una LE Connection Update Complete event
donde puedo ver que los parámetros de conexión solicitados se han tenido en cuenta.
Ahora, con una tableta Nexus 9 o con 2 dispositivos Nexus 5 diferentes, todos con Android 6.0.1, puedo ver que siempre se rechaza la L2CAP Connection Parameter Update Request
(recibo una L2CAP Connection Parameter Update Response
con 0x0001 (rechazado) ) Luego recibo un LE Connection Update Complete event
donde puedo ver que los parámetros de conexión solicitados NO se han tenido en cuenta.
He estado probando esto con 2 implementaciones diferentes en el lado periférico (una con BlueNRG de ST Microelectronics, otra con nRF52 de Nordic Semiconductor), ambas con exactamente el mismo resultado.
Luego, después de más pruebas: he probado diferentes conjuntos de parámetros, cambiando el intervalo de conexión máxima (mantuve otros parámetros iguales). Esto es lo que encontré:
- con intervalo de conexión máximo = 18.75 ms, se aceptó la solicitud de actualización con un intervalo establecido en 18.75 ms
- con intervalo de conexión máx. = 17.50 ms, se aceptó la solicitud de actualización con el intervalo establecido en 15.00 ms
- con intervalo de conexión max = 15.00ms, se aceptó la solicitud de actualización con el intervalo establecido en 15.00ms
- con intervalo de conexión máximo = 13,75 ms, se aceptó la solicitud de actualización con un intervalo establecido en 11,25 ms
- con conn interval max = 11.25ms, se aceptó la solicitud de actualización con el intervalo establecido en 11.25ms
- con cualquier otro valor máximo de intervalo de conexión inferior a 11.25ms, me rechazan.
Entonces la observación es que algo ha cambiado claramente con la forma en que la pila BLE de Android 6 maneja los parámetros de conexión. Pero no parece haber ningún tipo de información o documentación para confirmar eso.
Mis observaciones conducen a la conclusión de que el intervalo de conexión mínimo permitido ahora es de 11.25ms (que realmente se ajusta a mis necesidades) en lugar de 7.5ms en versiones anteriores de Android. Pero habiéndolo encontrado empíricamente, me gustaría asegurarme de que no me faltan otras restricciones / reglas o si ese mínimo no sería dinámico, dependiendo, por ejemplo, del nivel actual de la batería ...
Lo que sería genial sería tener el equivalente de las Pautas de diseño de Bluetooth de Apple (ver §3.6) para aclarar cómo un periférico LE debe tratar este tema.
¿Alguien tiene el mismo problema o conoce alguna información más útil de Google?
11.25 ms es el nuevo intervalo de conexión mínimo. La razón por la que ya no permiten 7,5 ms es porque si transmites audio a través de Bluetooth al mismo tiempo, el audio puede volverse picado.
Compare el método connectionParameterUpdate () de GattService.java en AOSP 6.0.1_r17 frente a AOSP 5.1.1_r14. En ambos casos, la llamada llega hasta Buedroid en BTA_DmBleUpdateConnectionParams () en bta_dm_api.c con los mismos parámetros.
6.0:
switch (connectionPriority)
{
case BluetoothGatt.CONNECTION_PRIORITY_HIGH:
minInterval = 9; // 11.25ms
maxInterval = 12; // 15ms
break;
case BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER:
minInterval = 80; // 100ms
maxInterval = 100; // 125ms
latency = 2;
break;
}
5.1:
switch (connectionPriority)
{
case BluetoothGatt.CONNECTION_PRIORITY_HIGH:
minInterval = 6; // 7.5ms
maxInterval = 8; // 10ms
break;
case BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER:
minInterval = 80; // 100ms
maxInterval = 100; // 125ms
latency = 2;
break;
}
Esto podría ser una parte de la respuesta a tu pregunta. Aunque BLE permite hasta 7,5 ms de IC, no puedo especular por qué la capa de enlace no cambiará a CI inferior a petición de periféricos. No sé si alguna parte del código de Android controla el resultado de las negociaciones con un dispositivo periférico.
Google no ha proporcionado ninguna documentación sobre los cambios en la pila de Bluetooth LE con respecto a los cambios en los parámetros de conexión, aunque claramente ha habido algunos en Android 6.
Mi experiencia con ella ha sido la misma que la tuya, siendo que 11.25ms ahora es el intervalo de conexión más rápido permitido en Android 6+.
Mi conjetura sobre por qué no publican la documentación es que muchos fabricantes colocan sus propias pilas BLE en sus teléfonos (la BLE en Samsung y HTC se comportan de manera diferente a la de Android vanilla).
Otra observación que hice que causó una gran cantidad de problemas es que Android 6+ cambiará los parámetros de conexión de 2 a 6 veces antes de establecer los parámetros solicitados.
Observé que después de solicitar un intervalo de actualización de parámetros de conexión de 800ms a 1100ms, vi que el intervalo inicial regresaba a los 7.5ms, luego saltó a 48.75ms y luego saltó a los 1098.75ms que solicité. Luego me suscribí a las notificaciones en uno de mis servicios y el intervalo de conexión saltó nuevamente a 7,5 ms y luego a 1098.75 ms. Después de esto, se estabilizó a 1098.75ms durante la duración de la conexión.
Estas pruebas se ejecutaron en un Nexus 6 con Android 6.0.1
Obviamente, algunas cosas muy extrañas están sucediendo en la pila de Android 6 BLE.
Los chicos de Google cometieron un error en uno de los commits recientes en BlueDroid al definir BTM_BLE_CONN_INT_MIN_LIMIT
como 0x0009
que te da 1.25ms x 9 = 11.25ms. Para cumplir con el estándar, debe definirse como 0x0006
.