🎮 NVIDIA SHIELD Blake Controller 🎮

https://i.ibb.co/d44s9Ty/blake.png

Hola, mundo!

Con el cierre de Stadia, y la consiguiente liberación de su controlador, he pensado que quizás sea un buen momento para compartir un proyecto en el que trabajé algún tiempo hace varios años.

Me refiero a liberación del llamado "Shield Controller" (codename "Blake"). Se trata del mando fabricado por Nvidia para los dispositivos Shield y principalmente usado en su plataforma de juego en la nube.
Hablamos de la primera iteración del mando, sacado al mercado en 2015, ya que la segunda versión (del 2017) salió con soporte multidispositivo oficial.
Sin embago, la versión original del controlador usa un protocolo propio, conectándose al dispositivo de destino a través de WiFi. Si bien funciona como un controlador estándar por USB, nunca hubo drivers que expusieran toda su funcionalidad, ni soporte oficial inalámbrico fuera de la plataforma Shield.

En este post hablaré de los protocolos utilizados, métodos de conexión y drivers que nos permitirán usar el controlador en un equipo con el hardware y software apropiados.
Son cuestiones bastante técnicas que, si bien para muchos usuarios quizás suponga un inconveniete demasiado grande como para considerar el controlador para uso diario, no deja de ser además un proyecto de ingeniería inversa y hacking.

Requisitos:

- Sistema operativo basado en Linux
- Interfaz WiFi P2P-GO 5Ghz

Probado con éxito tanto en PC (con interfaz de red Intel AX200) como en Raspberry Pi 4.

El controlador:

Se trata de un mando de juegos muy bien equipado, con varios subsistemas:

GamePad con:

  • 8 botones: Y, B, A, X, LT, RT, L, R
  • D-Pad: Up, Down, Left, Right
  • 2 gatillos analógicos: LT, RT
  • 2 Sticks analógicos: LS, RS
  • Vibración con dos motores (grande + pequeño)

TouchButton con:

  • 4 botones táctiles independientes

TouchPad con:

  • Trackpad de gesto único
  • 1 botón táctil independiente
  • 4 botones dependientes entre sí

Audio con:

  • Salida y entrada de audio por jack de 3.5mm
  • Micrófono integrado

Cada subsistema puede ser independientemente programado con su correspondiente actualización de firmware.
Además de éstos, el mando incluye el chip OZMO2000, el cual gestiona la conexión WiFi, también actualizable.
Todo ello se alimenta con una batería recargable que permite hasta 40 horas de uso.

Firmware

Hasta donde he posido investigar, sólo han habido actualizaciones oficiales para dos de los subsistemas comentados:

  • GamePad, cuyo firmware incluye:
    • Versión
    • HID Report Descriptor
    • Vendor ID / Name
    • Product ID / Name
    • CRC
  • OZMO, cuyo firmware especifica:
    • Frecuencias, canales y velocidades de conexión soportadas

Conexión

Capa física

La conexión al dispositivo de destino se realiza mediante WPS (WiFi Protected Setup). Este es el mismo sistema usado por algunos routers que permiten la conexión a través de un botón (PBC: Push Button Connection). Es posible replicar este sistema de conexón en un equipo Linux:

# wpa_cli -i <interfaz_wifi> p2p_group_add persistent # Crea una interfaz P2P desde una física compatible
# wpa_cli -i <interfaz_p2p> wps_pbc # Inicia la escucha para disposivos push button connection


Tras esto, es necesario pulsar el botón de conexión del controlador hasta que empiece a parpadear. Una vez deje de parpadear, la conexión se habrá establecido. En este momento es posible analizar el intercambio de datos con el controlado en un programa de análisis de paquetes de red.
Sin embargo, al cabo de varios segundos, la conexión se cerrará automáticamente. Esto es debido a que, a demás de una conexión apropiada, es necesario que el dispositivo de destino entienda el protocolo de datos intercambiados. De no poder responder a dicho protocolo, el mando cerrará la conexión.

Capa enlace

Para poder mantener la conexión, es necesario un driver de red de capa 2. El controlador Shield utiliza uno llamado Ozwpan (Ozmo Wireless Personal Area Network). Se trata de un protocolo que codifica mensajes de intercambio USB en paquetes Ethernet. De este modo se consigue que el controlador comparta la misma implementación del firmware para conexiones de cable e inalámbricas.

A día de hoy, Ozwpan no tiene soporte en ningún kernel moderno, es por ellos por lo que he rescatado el driver y lo he actualizado para que funcione en distribuciones Linux actuales:

https://github.com/SkyNoxt/Ozwpan

Una vez instalado el driver de kernel, y conectado el controlador, es posible cargar el módulo:

# modprobe ozwpan g_net_dev=<interfaz_p2p>


Esto nos permitirá usar el controlador tal y como si estuviera conectado por USB. De hecho, para el dispositivo de destino no hay diferencia. También funcionan el auricular y el micrófono integrado. Además, la conexión WiFi tiene la ventaja de tener menos latencia que una conexión a través de Bluetooth.

Driver HID

Aunque tras su conexión el mando sea funcional, hay varias características que no funcionan por defecto, tales como el trackpad, o la vibración. Por ello he programado un pequeño driver HID para poder usar estas funciones extra:

https://github.com/SkyNoxt/SHIELD-Blake

Preguntas y respuestas:

Q - Es posible portar el proyecto para el uso del controlador en Windows?
A - Si bien es teóricamente posible, el soporte en Windows para WPS/PBC es muy limitado. Ciertas restricciones en el desarrollo de drivers para Windows constituyen otro factor limitante.

Q - Es posible programar y flashear un firmware custom para el controlador?
A - Sí. Las características comentadas, tales como el HID Report Descriptor, o el nombre del dispositivo pueden ser customizadas y flaheadas. El firmware actualiza un microcontrolador XMEGA dentro del mando, con lo que también es posible reprogramar cualquier función controlada por éste.
Para flashear, se puede usar la herramienta de líneas de comando "blake", incluída en el firmware de cualquier dispositivo Shield. También es necesario actualizar el CRC del fichero de firmware, o la herramienta lo rechazará.

Q - Cómo sé si mi interfaz WiFi es compatible?
A - Para saber si soporta P2P-GO:

$ iw list


Para saber si soporta WiFi 5Ghz:

$ iw reg get


Q - El mando no soporta WiFi 2.4Ghz?
A - Sí, el OZMO2000 lo soporta, y capturando tráfico entre un PC y el mando es posible ver que algunos paquetes de éste usan rangos de 2.4Ghz antes de la conexión. Sin embargo, en mis pruebas no he conseguido hacer que la conexión se realice completamente en 2.4Ghz.

Q - No soy capaz de usar wpa_cli para la conexión WPS.
A - Si tu dristribución de Linux usa Network Manager, intenta desactivarlo e iniciar wpa_supplicant independientemente. Esto es debido a que algunas combinaciones de hardware y drivers son incapaces de mantener conexiones simultáneas en una misma interfaz física. Esto podría ser muy inconveniente ya que significaría que no se podría conectar al mando y a internet al mismo tiempo, por ejemplo.

Q - El mando no se conecta al PC tras activar en éste PBC. Su botón de conexión sólo se apaga tras un tiempo de expiración.
A - Comprueba que la interfaz P2P se ha creado en un rango de 5Ghz. Incluso si la interfaz física lo soporta, es posible que no lo utilice debido al dominio regulatorio.

Q - Puedo conectar y listar el mando (por ejemplo en juegos o aplicaciones de pueba), pero no se registra ninguna entrada.
A - Algunos kernels requieren una llamada del sistema adicional para activar dispositivos HID. Mi driver HID no la hace, ya que en mis pruebas sólo ha habido un caso. Si esta ocurrencia se da más frecuentemente, es trivial actualizar el driver HID para soportar también estos kernels.

Y esto es todo de momento, hora de jugar!

Un saludo,

~Sky
0 respuestas