Garmin Vivofit. Mini-reversing

Me compré hace un mes una "pulsera de fitness" Garmin Vivofit que sirve para medir algunos parámetros de tu actividad física diaria: pasos realizados, tiempo inactivo, kilómetros recorridos, horas de sueño, calorías. También da la hora y te avisa con una barra de progreso de color rojo del tiempo que llevas parado. En la foto se ve la raya roja: el primer segmento, el largo, representa una hora de "inactividad", y cada nuevo segmento pequeño son 15 minutos más sin movimiento. Cuando la barra se completa sabes que llevas dos horas sin mover el culo. 

A los dos días ya tenía el análisis completo de mi actividad física:
- Ando bastante más del objetivo marcado (este valor cambia cada día y el algoritmo que lo calcula es "secreto")
- Paso mucho tiempo sentado (soy informático, ¿qué esperas?)
- Duermo poco (sign of the times)

Mi Vivofit en la muñeca y el adaptador ANT+  en el portátil

Así que en dos días descubrí que había contratado un consultor en forma de pulsera: te cobra 100€ por decirte de forma bonita lo que ya sabías hace tiempo.

Luego me puse a analizar cómo funciona la pulsera y a hacer un poco de "reversing". Sólo un poco. La pulsera se sincroniza con el servicio web (en "la nube") Garmin Connect donde deja los datos, se muestran los gráficos y, además, permite configurar el dispositivo (ponerlo en hora, actualizar el software, indicar las "pantallas" que quieres ver, etc.). Sin esta comunicación el cacharro no sirve para nada más que para ver la hora. Hay otros dispositivos de Garmin que usan el mismo servicio, por ejemplo relojes de entrenamiento, monitores cardíacos, etc.

Resumen de mi actividad en Garmin Connect

Configuración del dispositivo en Garmin Connect

Para todo esto, la pulsera necesita conectarse usando un ordenador o un móvil que tenga Bluetooth 4.0 o ANT+. Cada dispositivo tiene un ID único (3880920587, en mi caso) y cada usuario de Garmin tiene otro ID único. Así que tienes que dar de alta un usuario y cuando recibes la pulsera emparejar dispositivo y usuario. La pulsera no se conecta automáticamente, hay que forzar la sincronización cuando el dispositivo tenga a su alcance el móvil o el ordenador con el que está emparejado. La verdad es que funciona bastante bien.

¿cómo funciona esta comunicación?

Un mecanismo sencillo basado en HTTP. Cada vez que se inicia la sincroniación, la Vivofit pregunta al servidor (connectapi.garmin.com) si tiene "algo" pendiente. Para ello, envía su identificador.
VIVOFIT (pulsera) -> GARMIN (web)

GET /device-service/devicemessage/messages/?device_id=3880920587 HTTP/1.1
a lo que, en este caso, el servidor responde que no hay nada pendiente. Imagino que aquí se notificarán los cambios de configuración o algo importante. No es el caso de la actualización de software de la pulsera que se realiza de otra manera:
GARMIN -> VIVOFIT
{"serviceHost":"http://connectapi.garmin.com/","numOfMessages":0,"messages":[]}
A continuación, la Vivofit pregunta por la configuración para dejar los datos registrados. Otra vez, el ID de la pulsera sirve de clave.
VIVOFIT -> GARMIN

GET /UploadConfigurationService/UnitUploadSettings/3880920587?clientId=express-windows HTTP/1.1
a lo que, esta vez, el servidor responde:
GARMIN -> VIVOFIT
[...] 
{"DataTypes":[{"DataTypeName":"FIT_TYPE_32","UploadLocations":[{"Url":"http://connectapi.garmin.com/upload-service/upload/wellness","RequiresAuthentication":true,"RequiresUserConsent":true}],"ExpectedSources":[]}]}
Y en esta dirección la Vivofit "postea" los datos de actividad (que no he intentado descifrar)
VIVOFIT -> GARMIN

POST /upload-service/upload/wellness HTTP/1.1
[...]
Content-Type: application/octet-stream
Host: connectapi.garmin.com
Content-Length: 331
[...]
Este es, por ejemplo, uno de los bloques enviados. En esta prueba se enviaron 11 bloques de unos 2000 bytes de media cada bloque. Intuyo que cada bloque son los datos de un día:
0E 10 EC 03 3B 01 00 00 2E 46 49 54 E1 7B 40 00 00 00 00 07 03 04 8C 04 04 86 01 02 84 02 02 84 05 02 84 06 02 84 00 01 00 00 0B 26 52 E7 04 DD A5 2D 01 00 2D 07 03 00 00 00 20 40 00 00 17 00 07 FD 04 86 03 04 8C 02 02 84 04 02 84 05 02 84 0A 02 84 06 01 02 00 A0 8E B2 2D 0B 26 52 E7 01 00 2D 07 F0 00 EC 05 01 41 00 00 37 00 05 FD 04 86 03 04 86 04 04 86 1D 02 84 05 01 00 43 00 00 37 00 02 1A 02 84 18 01 0D 47 00 00 7D 00 03 FD 04 86 01 10 02 02 20 84 40 00 00 67 00 07 FD 04 86 00 04 86 03 04 84 04 04 84 07 08 86 05 02 84 01 02 00 00 04 DD A5 2D 24 F9 A5 2D 59 20 85 30 3C 01 E4 03 15 29 00 00 15 29 00 00 AE 08 06 01 01 04 DD A5 2D 1D 01 00 00 90 65 00 00 27 00 06 01 04 DD A5 2D 4C 05 00 00 50 BD 01 00 27 00 01 03 04 DD 08 01 04 DD A5 2D 1D 01 00 00 90 65 00 00 27 00 06 01 04 DD A5 2D 4C 05 00 00 50 BD 01 00 27 00 01 07 04 DD A5 2D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 28 32

La actualización de software también es interesante. La Vivofit envía un POST con un XML que contiene la información de su configuración y versión actual de software.
VIVOFIT -> GARMINPOST /Rce/ProtobufApi/SoftwareUpdateService/GetAllUnitSoftwareUpdates HTTP/1.1
[...]
<Device xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.garmin.com/xmlschemas/GarminDevice/v2 http://www.garmin.com/xmlschemas/GarminDevicev2.xsd" xmlns="http://www.garmin.com/xmlschemas/GarminDevice/v2">
<Model>
<PartNumber>006-B1837-00</PartNumber>
<SoftwareVersion>240</SoftwareVersion>
<Description>vívofit</Description>
</Model>
<Id>3880920587</Id>
[...]

<UpdateFile>
<PartNumber>006-B1837-00</PartNumber>
<Version>
<Major>2</Major>
<Minor>40</Minor>

</Version>
</UpdateFile>
<UpdateFile>
<PartNumber>006-B1837-01</PartNumber>
<Version>
<Major>0</Major>
<Minor>0</Minor>
</Version>
</UpdateFile>
</MassStorageMode>
</Device>
Es decir, que la Vivofit con ID 3880920587 y número de serie 006-B1837-00 tiene la versión de software 2.40. A lo que el servidor responde "actualízate a la versión 2.50, anda". Y le pasa una URL para descargar la nueva versión.
HTTP/1.1 200 OK
[...]

¤
AVigorous activity with HR monitor connected will clear Move bars.
8Fixed calories displayed when connected to a HR monitor.
SFixed issue with extra activities being created when disconnecting from HR monitor.
6Fixed issue with auto goal getting seeded incorrectly.
>Fixed heart rate based calories missing in end-of-day message.
Display heart rate zone '0'. vivofit *http://www.garmin.com/gcdfiles/license.txt" vivofit_250.( 2] 3http://download.garmin.com/software/vivofit_250.rgn 9bd7eae9893e8d1f5182ab7cd7a88c98 Üô B 006-B1837-00J 2.50P `
Lógicamente, lo siguiente que hace la Vivofit es descargar desde esa dirección el nuevo firmware. 
VIVOFIT -> GARMIN

GET /software/vivofit_250.rgn HTTP/1.1
Host: download.garmin.com
Connection: Keep-Alive

HTTP/1.1 200 OK
Server: Apache
ETag: "9bd7eae9893e8d1f5182ab7cd7a88c98:1396559803"
Content-MD5: m9fq6Yk+jR9Rgqt816iMmA==
Last-Modified: Thu, 03 Apr 2014 21:16:43 GMT
Accept-Ranges: bytes
Content-Length: 64092
Content-Type: text/plain
Date: Thu, 17 Apr 2014 13:45:46 GMT
Connection: keep-alive
4B 70 47 72 64 00 02 00 00 00 44 64 00 1B 00 00 00 41 C8 00 53 51 41 00 4F 63 74 20 32 35 20 31 39 39 39 00 31 34 3A 31 36 3A 31 33 00 2A FA 00 00 52 0E 00 00 00 00 00 20 FA 00 00 00 BF 01 48 01 49 08 47 14 FE 02 00 7D FD 02 00 40 BA 70 47 40 BA 70 47 40 BA 70 47 C0 BA 70 47 C0 BA 70 47 C0 BA 70 47 08 B5 EF F3 10 80 00 28 03 D0 00 20 69 46 08 70 09 E0 68 46 12 DF 00 28 05 D1 68 46 00 78 00 28 01 D0 01 20 08 BD 00 20 08 BD 08 B5 FF F7 E8 FF 00 28 02 D0 68 46 2B DF 03 E0 EF F3 10 80 00 90 72 B6 00 98 08 BD EF F3 05 80 C0 05 00 D0 01 20 70 47 10 B5 04 46 FF F7 D3 FF 00 28 02 D0 E0 B2 2C DF 10 BD 84 F3 10 88 10 BD 00 00 [...]
El fichero en formato RGN ocupa 64 KB. Encontré en Internet una herramienta para editar estos ficheros. La herramienta se llama RGN_tool
RGN_tool

Hasta aquí ha llegado mi análisis del funcionamiento interno de la Garmin Vivofit. Cosas que no he estudiado de momento (pero me gustaría):
- estructura de los datos de actividad (trolear al sistema para decirle que hoy he andado 520 km...),
- estructura del firmware de la pulsera (crear mi propia versión de firmaware. Esto me gustaría....),
- mecanismo de la sincronización de la configuración del dispositivo (formato de hora, pantallas que se muestran, etc.)
- mecanismo de sincronización de tiempo y precisión del mismo.

<Garmin Vivofit. Mini-reversing />