"Después del juego es antes del juego"
Sepp Herberger

jueves, 30 de abril de 2015

OpenWrt+USBIP+Smartboard 680 (Episodio I)

Ye he relatado mas de una vez la relación de amor/odio que tengo con las pizarras SmartBoard. En este caso me tocó enfrentarme con una SmartBoard 680: recordemos que tanto la alimentación como el flujo de datos van por el mismo cable USB, de tal forma que si el cable es demasiado largo (mas de 2 o 3 metros) la conectividad de la pizarra se resiente bastante, perdiendo la señal continuamente y haciendo inmanejable el instalache.

En este caso tengo un aula con una organización peculiar que hace que la distancia del PC a la pizarra fuese de mas de 10m. En principio compramos un cable USB activo, porque nos aseguraron que eso iba a funcionar. Ni de coña: la señal de la pizarra era solo un poco mas estable, pero al final acababa perdiendose la conexión y fallando el driver en el momento mas inoportuno.

¿Estaba todo perdido?. Pues no nos resignamos: el que no llegue el cable USB no quiere decir que no se pueda meter la señal USB por un ordenador o dispositivo, encapsularla en paquetes TCP/IP y hacerla llegar hasta el ordenador del profesor en el cual está el software de la pizarra: es lo que se llama USBIP. La idea es sencilla:

  • Conectamos la pizarra a la entrada USB un "servidor usbip" que esté cercano, para poder usar un cable corto que nos garantice una conexión estable.
  • En ese "servidor usbip" comparte  desde su IP la conexión USB a la pizarra mediante el demonio "usbipd".
  • El ordenador del profesor actúa de "cliente usbip" y se conecta al dispositivo USB compartido desde el "servidor usbip" mediante el programa cliente  "usbip", creando un puerto usb virtual, que está enganchando mediante un túnel TCP con la conexión USB de la pizarra.
  • El resultado final es que se engaña al driver, que se piensa que la pizarra (o el dispositivo que sea) está efectivamente conectada a un puerto USB del ordenador del profesor.

Un esquema visual:

¿Que utilizamos como "servidor usbip"?. Primero pensé en algún PC antiguo, con pocos recursos ya que no se necesita mucho hardware para ejecutar el servicio. Luego pensé en una Raspberry Pi, que además es pequeña y resultona. Pero al final escogí lo mas divertido: podía usar un router ADSL viejo que tuviese entrada USB y permitiese instalar OpenWrt, ya que tiene soporte para usbip.

El router ADSL elegido es un ARV7518PW, que era un router blanco Astoria que daba Ya.com:

Es un router que tiene un puerto USB, memoria flash de 8Gb y en el que, con ciertas precauciones, se puede instalar OpenWrt. También tenia el modelo anterior, un ARV4518PW de color gris, pero no lo usé ya que solo tiene una memoria flash de 4Gb y andaba un poco justito para meter el Openwrt.

La instalación de OpenWrt es un poco mas complicada que la que hice hace un tiempo para un Huawei, ya que hay que conectar por el puerto serie interno del router y reemplazar el brnboot por uboot (esto es como la bios+grub del router) y enviar la imagen con el OpenWrt. No es difícil siguiendo estas guías paso a paso:

En ambas guías se habla de instalar (o compilar desde cero) la versión 12.09 (Attitude Ajustement) de OpenWrt, pero yo me decanté por usar la versión 14.07 (Barrier Breaker), ya que cuando se hicieron esas guías todavía no había salido una versión estable de ésta. La causa es que el software es mas moderno y que se soluciona un bug en el driver la tarjeta wifi que hacía que solo funcionase a una potencia de 3db, permitiendo ahora ponerla hasta 20db y freir el cerebro de todos los hipocondriacos en varios cientos de metros a la redonda. La URL del sistema Barrier Breaker para este router, ya preparado para flashear es: https://downloads.openwrt.org/barrier_breaker/14.07/lantiq/xway/openwrt-lantiq-xway-ARV7518PW-squashfs.image.

Bueno, una vez tenemos el Barrier Breaker en el router, lo hemos conectado a la red por cable, puesto una IP fija y hemos cambiado la contraseña de root, nos conectamos a él por ssh como a cualquier otro Linux OpenWrt y empezamos a configurarlo para convertirlo en un servidor usbip, vamos allá:

# opkg update
# opkg install kmod-usbip kmod-usbip-client kmod-usbip-server
# opkg install kmod-usb-ohci
# opkg install libsysfs libwrap
# opkg install http://downloads.openwrt.org/attitude_adjustment/12.09/lantiq/danube/packages/usbip_1.1.1-2_lantiq.ipk
# opkg install http://downloads.openwrt.org/attitude_adjustment/12.09/lantiq/danube/packages/usbip-client_1.1.1-2_lantiq.ipk
# opkg install http://downloads.openwrt.org/attitude_adjustment/12.09/lantiq/danube/packages/usbip-server_1.1.1-2_lantiq.ipk
# reboot

Con esto instalamos los drivers y el software, después de reiniciar verificamos si está todo:

# opkg list-installed | grep usbip
kmod-usbip - 3.10.49-1
kmod-usbip-client - 3.10.49-1
kmod-usbip-server - 3.10.49-1
usbip - 1.1.1-2
usbip-client - 1.1.1-2
usbip-server - 1.1.1-2
#

Ahora enchufamos la pizarra al puerto USB del router y vemos si la detecta:

# opkg update
# opkg install usbutils
# lsusb
Bus 001 Device 001: ID 0b8c:0001 SMART Technologies Inc.
#

Ahi está. Veamos si se puede compartir con usbip:

# usbip list -l
Local USB devices
=================
 - busid 1-1 (0b8c:0001)
         1-1:1.0 -> usbip-host
#

Ahi está, conectada al bus 1-1, que es como lo identifica usbip. Para que se comparta el usb cada vez que arranque el sistema operativo del router  lo mejor es meter en /etc/rc.local el código siguiente:

# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.

usbipd -D &
sleep 1
usbip bind -b 1-1

exit 0

Son dos instrucciones: "usbipd -D", que arranca el servidor en modo daemon, y "usbip bind -b 1-1" , que enlaza el servidor usbip con el dispositivo conectado al bus 1-1, en este caso la pizarra Smart, de tal manera que dicho dispositivo queda compartido por el demonio.

Reiniciamos y, suponiendo que 172.20.41.57 es la IP del router donde tenemos conectada la pizarra,  al hacer:

# usbip list -r 172.20.41.57
Exportable USB devices
======================
- 172.20.41.57
1-1: SMART Technologies Inc. : unknown product (0b8c:0001)
: /sys/devices/platform/ifxusb_hcd/usb1/1-1
: (Defined at Interface level) (00/00/00)
: 0 - Human Interface Device / No Subclass / None (03/00/00)

Nos aparece la pizarra lista para conectar a ella. Una comprobación mas:

#  netstat -alpt
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:3240 0.0.0.0:* LISTEN 1079/usbipd
tcp 0 0 0.0.0.0:domain 0.0.0.0:* LISTEN 1015/dnsmasq

Ahí tenemos el demonio usbipd esperando conexiones por el puerto 3240, para exportar la conexión USB de la pizarra a quien quiera conectarse a él.

Bueno, ya tenemos la parte servidora. En la próxima entrada veremos la parte cliente, que puede ser en Windows o en Linux.

 

No hay comentarios:

Publicar un comentario