
No tengo captura del enunciado pero decía algo así como:
«HACK IT 2: Pilas Duracell»
«Otra de señales. A ver si nos ponemos las pilas!».
Y teníamos un enlace para descargar un fichero:

Si miramos el tipo de fichero que es:

ASCII? vamos a abrirlo:

Y alguno igual ya dirá … .vcd, está claro qué es, tó esto sobra … bueno, pues yo hasta el sábado pasado no tenía ni idea ni de qué tipo de archivo era este, ni de dónde venía, ni pa qué sirve, ni cómo se ve, ni qué contiene, ni absolutamente ná de ná … lo más semejante que he visto nunca ha sido los video cds de hace años (amos, nada que ver).
Total, que buscando un poco por la wiki encontramos que VCD viene de las siglas «Value Change Dump» y lo que parece contener es información de señales a lo largo del tiempo. En este caso tenemos una única señal:
$var wire 1 ! pin[0] $end
El valor de esta señal está representado por lo que acompaña al ‘!’ y esta es el pin[0] … y como digo no hay más…
Por otro lado, el tiempo, estará representado por el valor que hay después de ‘#’. Y esto no me lo he inventado, viene en la wiki:


Para tener una idea global del aspecto de la señal podemos utilizar un aplicación (que encontré buscando en google pa variar) y que se llama Gtk Wave:

Al arrastrar la señal a «Signals» aparece el valor de la misma a lo largo del tiempo. Si hacemos un poco de zoom out podremos ver cómo pasa a valer 1 la señal a los 20 nanosegundos (como bien indica el fichero .vcd):



Todos y cada uno de los tramos que se ven en la captura de en medio tienen un aspecto semejante al de la captura inferior.
Vale, ¿y ahora que?
Pues como yo personalmente no sé si existe alguna aplicación que decodifique/capture directamente estas señales para pasarmelas a datos numéricos, opté por hacer el proceso desde cero a mano con un programilla hecho usando matlab/octave:

Esto hace la lectura del fichero línea a linea hasta la línea 12:

amos, elimina lo que no me interesa ya que yo lo que quiero son los tiempos.
A partir de aquí, si hacemos lo siguiente:

Sencillo, voy leyendo línea a línea y me voy quedando con el valor que hay después de la # (es decir con los tiempos). El valor que toma el pin[0] en esos tiempos no me resulta relevante porque sé que va a ir SIEMPRE alternando 1-0-1-0-1-0-… y también sé que parto del valor 0 porque mi primer valor de tiempo es 1080840604 nanosegundos y:

Y ahora viene el tema de cómo obtener la señal que hemos visto antes en el GTK wave pero para poder tener una tira de 1’s y 0’s y que pueda hacer algo con ellos. Para ello, en primer lugar, lo que tengo que hacer sencillamente es ir recogiendo todos los valores de tiempo que he leído del fichero y, de 2 en 2, ir restando el valor siguiente al valor actual; es decir:

Con esto lo que tengo es un array de diferencia de tiempos, es decir, en la posicion 1 de diffs tengo el tiempo que va a haber 0’s en el ‘cable’ en la posición 2 de diffs tengo el tiempo que va a haber 1’s, en la 3 el tiempo que va a haber 0’s de nuevo, etc…
Si represento esas diferencias en una gráfica tengo lo siguiente:

A ver… esto no dice mucho porque en en torno a diff(3500) la cantidad de 0’s o 1’s seguidos que hay es muy tocha… vamos a hacer zoom a la parte inferior de la gráfica que es donde tendremos algún dato interesante…


Aquí podemos ver cómo el mínimo valor de tiempo en el que cambia de valor la señal de pin[0] está en torno a 1500 ns…
Como vemos no es exacto… y es más, hay algún que otro valor más pequeño aún:

Pero a ver, creo que no hace mucha falta explicar por qué vamos a coger 1500 como unidad mínima y no 667 (que es el valor del pico de la imagen anterior)… la vida es imperfecta … 😛
Vamos con el meollo del asunto… mi idea ahora es representar con un 1 o un 0 un margen de tiempo de 1500ns en la señal; es decir, quiero hacer esto básicamente:

Para hacer esto se nos plantea algún problema…
Los «tiempos muertos», o sea, donde no se está transmitiendo nada en el cable, aparecerán un mogollonazo de ceros … que sinceramente no sirven para nada y molestarán bastante así que vamos a intentar sortearlos.
Si nos fijamos un poco en la señal NUNCA hay más de 2 ‘bits’ iguales seguidos


NUNCA
Esto nos ayudará luego a deducir una cosilla, pero de momento vamos a utilizar esta propiedad de la señal para hacer lo que necesitamos:

La clave del programilla de arriba es dividir cada una de las diferencias que hemos calculado previamente entre 1500 y quedarnos con el número redondeado y escribir tantos 1’s o 0’s como ese número. Además, si la división sale mayor que 3, significará que estamos en zonas de 0’s, así que las obviamos de un plumazo directamente.
De esta forma tenemos lo siguiente:

No se aprecian mucho; haciendo un poco de zoom en alguna:

Tenemos lo que buscábamos … o al menos tiene mucha pinta así que de momento bien …

Y bueno con esta información, ahora podemos empezar … está guapo no hemos empezado realmente a intentar resolver nada, solamente estábamos transcribiendo los datos… xD
Y bueno, aquí viene lo tocho… para continuar había que interpretar bien la pista que hay en el título «Pilas Duracell». Del título como digo, sacamos PD -> USB-PD (Power Delivery)
Yo, al ver ese tipo de señal, supuse que podría ser codificación Manchester que tiene esta pinta:

Pero tras pasarlo a manchester y perrear con los bits parriba y pabajo no llegué a ninguna conclusión…
Si buscamos documentación del protocolo USB-PD nos topamos … en primer lugar, con la codificación que lleva sobre la propia señal, que es la que nos interesa:

Ahora, si buscamos cómo va el BMC:

Una de las ventajas de este tipo de señales (ya a nivel informativo, no es relevante para el hack-it 😉 es que el clock lo llevan integrado en la misma señal y por eso NUNCA hemos visto más de dos 1’s o dos 0’s seguidos en la señal que nos ha pasado marcan.
Bueno, vamos a decodificar la señal BMC para obtener los datos que queremos:

Lo que hace este programa básicamente es ir leyendo los bits que tengo en ‘signal’ de 2 en 2 y comparar su valor; si los valores son iguales => ‘0’ ; si son diferentes => ‘1’. Y de este modo obtenemos:

Bueno, pues ya tenemos todo decodificado … o no… porque … qué hacemos ahora con todo esto?
Pues seguir leyendo cómo va el protocolo USB-PD (aquí dejo la especificación de USB-PD por cierto):
Una trama USB-PD tiene esta pinta:


Bueno, pues esta parte la tenemos facil … 10101010…. hasta 64 bits cuadra:

A ver qué tenemos lo siguiente:

Y aquí se viene un poco el lío porque los bits se van a leer al revés y de 5 en 5. ¿que por qué? pues porque lo pone en las especificaciones del protocolo xD; en primer lugar el bit ordering:

El que se transmite primero es el bit de menos peso en su bloque correspondiente con lo que si seguimos por ejemplo con esta trama:

ese 00011 se tendría que leer -> 11000 y así con todos los bloques.
He cogido 5 bits por la codificación:

Tras el preámbulo va el SOP, como hemos visto en alguna captura anterior, y este SOP consta de 4 bloques de 5 bytes en total.
Sabiendo todo esto, vamos a eliminar los preambulos y los SOP y vamos a transformar los headers y los datos de todas las tramas. Lo hacemos con este código:
Primero voy a poner en variables en líneas separadas cada una de las tramas:

Así puedo trabajar con cada línea de forma individual más cómodamente.

Y ahora se viene el programa gordo y que explicaré un poco por encima porque línea a línea es una locura …

Lo que hace este programa es básicamente coger de 5 en 5 bits todas las tramas que contiene ‘bmc_lines’ y las pasa a hexadecimal (decodificándolo según la tabla 4b5b, que como veis, he invertido los bits directamente en la tabla de conversión, en lugar de hacer la lectura en orden y usar la tabla de conversión sin invertir).
Si visualizamos los datos aqui obtenidos veremos lo siguiente:

Con todo este chorizo de datos ya decodificados, no habría ya más que hacer pruebas a ver si se ve algún texto por ahí.
Si juntamos las cifras de 2 en 2 (ya que 1 byte en hexadecimal son 2 digitos de los que se ven en la captura), luego lo podríamos pasar a ascii:


No se ve nada … pero hay que tener en cuenta que los datos nos vienen invertidos con lo que hay que dar la vuelta cada una de las parejas de dígitos:


Y por fin, … ahí esta:
