Mostrando entradas con la etiqueta robot. Mostrar todas las entradas
Mostrando entradas con la etiqueta robot. Mostrar todas las entradas

22 junio 2011

Vigilando tu casa con Rovio

Tiempo llevaba dándole vueltas a la posibilidad de comprar otra Roomba, lo más barata posible, vieja, de segunda mano, o como fuera,.. únicamente para trastear, puesto que la otra tiene la importante misión de dejar la casa limpia diariamente.

La idea era ponerle una webcam y poderla guiar por casa en remoto y que me muestre cómo está todo. Comentando esto con mi amigo Alex me comentó que había ya un robot llamado Rovio con webcam integrada, que a lo mejor me interesaba más para añadir a la colección de bichos que conforman el Skynet de mi casa, en vez de repetir con otra Roomba.

Buscando diversas opciones en Amazon, Ebay, etc,… el precio no bajaba de los 160 euros, hasta que en segundamano dí con un chico de Madrid que tenía uno sin usar, por bastante menos dinero. Así que quedé con él y nos pegamos un domingo por la tarde probándolo en su casa. La unidad tenía bastante buena pinta así que dije: para mí!

La configuración del cacharro se hace bastante rápido vía wireless, permitiendo cifrados WEP, WPA y WPA2.

Los únicos puertos abiertos son:

[root@Carmen ~]# nmap -sT 192.168.1.13

Starting Nmap 4.20 ( http://insecure.org ) at 2011-06-17 08:20 CEST
Interesting ports on 192.168.1.13:
Not shown: 1695 closed ports
PORT    STATE SERVICE
80/tcp  open  http
554/tcp open  rtsp
MAC Address: 00:12:34:56:78:90 (CyberTAN Technology)
Para manejarlo se utiliza una interfaz web que proporciona mediante el servidor web embebido en el propio robot.




Trasteando con Tamper Data por ejemplo, se puede ver que el mecanismo de comunicación para dar órdenes al robot es muy sencillo.

Han implementado Basic Authentication en HTTP para poder acceder al panel, y son todo el rato llamadas a un CGI modificando dos parámetros: action y drive (opcionalmente está el parámetro "speed" que por las pruebas que he hecho no da para mucho más).

Así pues hice un programilla "supercomplicado" en perl que permite hacer que el bot se mueva para donde queramos según le pases por comando

[root@Carmen ~]# more rov.pl 
#!/usr/bin/perl
use LWP::UserAgent;

$IP_Rovio="192.168.1.13";
$Auth="Elhashquetoque";

my $url="http://".$IP_Rovio."/rev.cgi";
my $browser = LWP::UserAgent->new;
my $response = $browser->post(
    $url,
    "Pragma" => "no-cache",
    "Cache-control" => "no-cache",
    "Authorization" => "Basic $Auth",
    "Content" => [Cmd=>'nav', action=>'18', drive=>$ARGV[0]] 
);
Para hacer que se mueva, el parámetro action tiene que ser = 18.

En el parámetro drive decimos la dirección hacia donde tiene que ir. Fuzzeando dicho parámetro vemos lo siguiente:

1 adelante
2 atrás
3 izquierda
4 derecha
5 rota a la derecha (muy poquito. 1 grado?)
6 rota a la izquierda (muy poquito. 1 grado?)
7, 8, 9 y 10 hace moverse el robot a izquierda y derecha empujando con dos de las ruedas en vez de con una sola. Es parecido a 1, 2, 3 y 4
17 Rota a la derecha unos 15 grados (Necesario después de un action=33 para cancelar un Go_Home)
18 Rota a la izquierda unos 15 grados

La webcam que trae incorporada dispone de tres posiciones: abajo, media o levantada. Para seleccionar la posición, con el parámetro action=18, pasamos los valores 11, 13 y 12 al parámetro drive para hacer que esté arriba, a media altura o abajo del todo, respectivamente.

Si queremos encender o apagar un "led" que trae para poder ver algo mejor lo que la cámara envía, haremos la llamada con action=19 y un parámetro LIGHT con valores 0 ó 1.

Si simplemente queremos monitorizar el estado del robot, pasamos el valor 1 al parámetro action y nos devuelve algo como lo siguiente:

[root@Carmen ~]# perl rov.pl   
Cmd = nav
responses = 0|x=-385|y=413|theta=-0.347|room=0|ss=43
|beacon=22|beacon_x=5183|next_room=-1|next_room_ss=0
|state=0|ui_status=0|resistance=0|sm=15|pp=0|flags=0007
|brightness=6|resolution=0|video_compression=0|frame_rate=5
|privilege=0|user_check=1|speaker_volume=21|mic_volume=20
|wifi_ss=199|show_time=0|ddns_state=0|email_state=0
|battery=116|charging=0|head_position=203|ac_freq=1
Entre otras cosas, la batería que le queda, si se está cargando o no, datos de la potencia de señal wireless, el volumen del altavoz y del micrófono (se supone que puedes hablar con la gente a través del robot estando conectado al interfaz web desde donde sea), etc,…

Rovio permite además hacer un snapshot de lo que la cámara está viendo en ese preciso momento y enviarlo a una dirección de correo electrónico predefinida. Para eso el valor del parámetro action debe ser 26.

Para hacer que el robot vaya a su dock a cargarse, hay que enviar en action el valor 13.

El streaming de lo que va mostrando la webcam incorporada en el robot, se puede ver mediante http://IP_Del_rovio/GetData.cgi?width=640px&height=480px afinando la resolución deseada.

Ya hay aplicaciones para controlar Rovio desde iPhone y desde Android, aunque con todos estos datos que hemos comentado, deberíamos ser más que capaces de hacer cualquier otro tipo de interfaz de comunicación con el robot: como un programa en modo texto mediante teclas por ejemplo; o que cuando estemos de vacaciones haga un recorrido diario predefinido, que vaya haciendo snapshots y nos los vaya enviando por email,… O incluso se puede tener otro programa que coja todas esas imagenes y genere un video, que sea lo que recibamos finalmente en nuestro correo. De esa manera podríamos ir recorriendo el recinto y ver el estado en fotos de las habitaciones deseadas, que como podéis imaginar, es algo que el cacharro no es capaz de hacer por si solo.

La gracia de este tipo de robot es poder utilizarlo cuando no estás en casa y moverte con él. Sin embargo, al ser el interfaz de configuración y monitorización a través de HTTP y la autenticación básica, quizá no sea una buena idea el mapear un puerto del router directamente al servidor web del Rovio y dejar en manos de la bondad del mundo que un ataque de fuerza bruta/diccionario permita sacar la contraseña y el robot se mueva por casa a voluntad de otros.

En mi caso, que desde mi Mac puedo realizar una conexión VPN hasta mi casa, no hay problema, porque no tengo que exponer ningún servicio nuevo hacia fuera. Sin embargo, desde el iphone me gustaría acceder de forma directa.

Para ello he establecido alguna medida de seguridad extra para asegurar que desde fuera soy yo y solo yo quien accede.

Dispongo de un PC entre las redes confiables de casa y el router que me conecta a Internet. En él, tengo un Apache al que he realizado las siguientes modificaciones en el fichero httpd.conf:

<virtualhost ip_externa:puerto>
ServerName lorenzomartinez.es
ProxyRequests Off
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
SSLCertificateFile /unaruta/serverpem.pem
SSLCertificateKeyFile /otraruta/serverkey.key
SSLCACertificatePath /otrasrutamas/_ssl_.crt
SSLCACertificateFile /laultimadelasrutas/ca.crt
SSLVerifyClient require
SSLVerifyDepth  10
SSLOptions +OptRenegotiate
ProxyPass / http://192.168.1.13/
ProxyPassReverse / http://192.168.1.13/
CustomLog logs/rovio_log combined
</virtualhost>

Lo que hemos hecho es crear un Virtualhost que requiere un certificado SSL X.509  de cliente, firmado por una CA interna que, si todo es correcto, y gracias a mod_proxy, Apache hará las peticiones al servidor del robot Rovio. La comunicación hasta mi casa va cifrada y autenticada con el certificado SSL y entre mi máquina y Rovio, va por HTTP con cifrado WPA2 establecido por la propia red wireless.
Ya comentamos hace tiempo en SbD qué herramienta se puede utilizar para introducir el certificado digital en el iPhone. Otra opción sería dejar el certificado accesible en un servidor web  privado y añadirlo al keystore del iPhone.

Conclusiones:
  • La idea de tener un robot en casa que puedas manejar desde donde estés, suena muy friki y permite pensar en cuánto juego te va a dar.
  • El precio del robot es bastante elevado, a no ser que encuentres uno de segunda mano (aunque en perfecto estado) a muy buen precio como el que compré yo, ni se me pasaría por la cabeza comprarlo
  • Como webcam wireless que es, podría integrarlo y dejarlo activo como una webcam más controlada por Motion, y si detecta un movimiento, que avise. El problema es que cuando diéramos una vuelta con el robot, manualmente, daría un montón de falsos positivos
  • Se supone que las baterías las cargas durante 4 horas y media, el robot dura una hora y media moviéndose. En mi caso, el robot no termina nunca de cargar las baterías, permaneciendo un montón de luces encendidas del mismo (de noche parece una nave espacial como podéis ver en la foto de arriba). Por supuesto la batería dura menos de lo deseado y de lo especificado.
  • Leyendo (a posteriori… damned!) las experiencias de otros compradores de Rovio en Amazon, dan ganas de no comprarse un bicho de estos: Efectivamente la batería dura 15 minutos, el soporte de WowWee es lamentable, tardan semanas en contestar y finalmente te dicen que no es su problema, la calidad de la webcam es bastante mala cuando aun a ojos humanos hay suficiente luz.
  • Existe un accesorio que permite añadirle más luz al robot (incluso le da un aire a Johnny Número 5), y así poder monitorizar el recinto de noche. Sin embargo, el artículo está descontinuado y no hay manera de comprarlo, al igual que cualquier otro Rovio, lo cual tampoco aporta mucha fe en este tipo de producto. En Hackaday publicaron un DIY para añadirle más leds que permitan ver algo cuando las condiciones de luz empiezan a flaquear.
  • La calidad del producto no es ni de lejos la de la Roomba. Rovio cuando está en modo: "vete al dock", se nota que cuando choca con un obstáculo, tarda en detectar que eso ha pasado y que tiene que intentar moverse hacia otro lugar. Roomba en cambio, detecta cuándo va a chocar, ralentiza su movimiento para impactar despacito y gira sobre sí misma para buscar otra forma de llegar a la base. Además para poder ir al dock de forma directa, Rovio necesita tener diferentes captadores que le guíen en diversas habitaciones, en cambio Roomba va buscando con calma donde está la base cuando pueda.
  • Como ventaja ante Roomba es que Rovio trae un interfaz wireless ya incorporado, y no hay que hacer malabarismos para lograr algo vía bluetooth como en el caso del "robot redondo"
  • En definitiva, Rovio es un producto con más ambición invertida en el márketing que en la calidad del producto en sí (parece demasiado de juguete), la parte del audio sólo funciona con Internet Explorer, no tiene un modo standby,…
  • Una pena que en mi búsqueda de un novio para mi Roomba, me haya equivocado con un robot mediocre que sólo puede funcionar de día, poco rato, y con todas las luces puestas. 
  • Afortunadamente, el chico que me vendió el Robot me ofreció la oportunidad de devolvérselo si el equipo no cumplía con mis espectativas. Después de hablar con él, y a la vista de los problemas del robot, y de manifestarle que efectivamente, no me va a valer para mucho en estas condiciones, no sólo me ha dicho que me devuelve el dinero, sino que si el producto no da buen resultado, y dado que para él también fue un regalo y que ve que a mí me encantan estas cosas y que "lo vivo", me quede además con el robot. Es increíble y loable que queden personas así de honradas en este mundo! La verdad es que pasamos una tarde de domingo bastante divertida inicializando el cacharro (casi me tengo que quedar a ver la Fórmula 1 en su casa!). Me contó que tenía un grupo de música llamado "Ojos de Gamba" e incluso me regaló un disco! Muchísimas gracias Israel!
Leer más...

17 enero 2011

Hacking Roomba!

Para quien no lo conozca, Roomba es un modelo de las aspiradoras inteligentes de iRobot. Este tipo de dispositivos pretenden, a un coste bastante elevado, todo hay que decirlo, hacer la vida más cómoda al propietario, librándole de pasar la aspiradora manualmente.

No sé realmente si la razón de que estuviera detrás de una Roomba, era el mantener la casa limpia o el poder "meterle mano a la chacha" (en el buen sentido de la palabra, al ser un robot).

Así pues, y tras leer el libro "Hacking Roomba" (muchas gracias por el ejemplar a Raúl) me dije que esto, simplemente había que probarlo y si no, a las malas, tendría la casa más limpia.

Así pues encargué el modelo 555, que permite programación manual utilizando una botonera en el propio aparato. Lo primero que pensé: "Esto lo programaré en remoto, sin agacharme!"

El objetivo principal era poder decirle a la Roomba: "Ponte a aspirar AHORA" o "Vete a tu base de carga YA!", desde el servidor de casa, controlando vía cron o de forma manual esas operaciones a voluntad.

Así pues, para hacer frente al problema se me pasaron por la cabeza varias opciones. Existe un mando a distancia por Radiofrecuencia que permite ejecutar las mismas operaciones desde cualquier parte de la casa, en la que tengas el mando. Sin embargo, no es compatible más que con el modelo superior: el 581. La siguiente alternativa era utilizar un mando a distancia compatible con todas las roombas. En este caso, funciona mediante Infrarrojos. por lo que podría hacer un cable al puerto serie con un diodo IR y mediante LIRC, grabar la ejecución de cada operación y reproducirla después. Sin embargo, para poder controlar la roomba en toda su inmensidad, la opción más interesante, potente y versátil era utilizar un interfaz bluetooth.

Para los que como yo, no seais muy manitas con el soldador y  los cables, en Sparkfun, venden interfaces bluetooth ya hechos, llamados Rootooth que son "más o menos" plug & play….

Para meterle mano a la Roomba via Bluetooth, esto es lo que debéis hacer:

  1. Enchufar el dispositivo bluetooth a la Roomba. Consejo: sujetad con cinta aislante el cable y el conector, porque dado el movimiento de la roomba, puede sufrir daños. Al principio lo tenía como la foto que se puede ver en el avatar del post.
  2. En mi caso he utilizado Linux con un adaptador Bluetooth para poder conectarnos al Rootooth.  Mediante hcitool buscamos el nuevo dispositivo Bluetooth y nos apuntamos la MAC.
[root@Carmen ~]#  hcitool scan 
Scanning ...
    00:06:66:ZZ:XX:YY    FireFly-XXYY

3.-) Probamos a establecer una conexión mediante "rfcomm" que, una vez hecha la conexión, nos dejará un puerto en /dev/rfcommN al cuál podremos hablar como si de un puerto serie se tratara.

[root@Carmen ~]# rfcomm connect 2 00:06:66:ZZ:XX:YY
Connected /dev/rfcomm2 to 00:06:66:ZZ:XX:YY on channel 1
Press CTRL-C for hangup

4.-) Lo siguiente es comprobar que el modem que incluye Rootooth funciona correctamente a 115200 bps, para no tener errores en la comunicación. Para ello accedemos mediante "minicom" y comprobamos que todo está correcto:

Welcome to minicom 2.00.0


OPCIONES: History Buffer, F-key Macros, Search History Buffer, I18n
Compilado en Feb 21 2005, 19:32:30.


Presione CTRL-A Z para obtener ayuda sobre teclas especiales
                                                  
CMD                                               
?                                                 
***Settings***                                    
BTA=000666ZZXXYY                                  
BTName=FireFly-XXYY
Baudrt=115K
Parity=None
Mode  =Slav
Authen=0
Encryp=0
PinCod=1234
Bonded=0
Rem=NONE SET
END

Una vez que conecta, enviamos los caracteres "$$$"(3 símbolos del dólar, sin las comillas) para entrar en modo Comando al modem Bluetooth. Nos contestará con CMD si todo es correcto. Pulsando D y Enter, nos dará la info que se puede ver más arriba. Importante que esté a 115K, y Parity None. Si algo no está como debe, con la tecla H se accede a la ayuda y se configura para que quede así.
Una vez todo está correcto, pulsamos "---" (tres guiones seguidos, sin comillas) y devolverá END… Ya estamos fuera del modo command.

5.-) Después de probar diversos programas (RoombaCom, Roomba-tilt.pl, Roomba Status) rebuscando en Internet, que prometían controlar la Roomba en remoto, y ver que estaban todos obsoletos, decidí buscar documentación actualizada de la API de la Roomba para poder hablarle.

El documento actualizado para las especificaciones Open Interface de la serie 500 se puede descargar de aquí.

6.-) Manos a la obra… Bajo estas líneas pongo un script (por supuesto en Perl) que recibe como parámetro "clean" o "dock" y hacen que la roomba se ponga a limpiar o se ponga en modo Dock (o, ir a su base de carga)

Incluyo además el código necesario para que cada vez que lo ejecutemos, cree una conexión nueva contra Rootooth, no teniendo que mantener el rfcomm abierto todo el tiempo.

[root@Carmen tmp]# more /usr/local/bin/roomba.pl 
#!/usr/bin/perl

use IPC::Open2;

$port="/dev/rfcomm2"; #el puerto serie a crear. Importante que no esté siendo usado ya
my $param=lc ($ARGV[0]); #capturo parámetro introducido y lo paso a minúsculas
my $rfcomm="rfcomm connect 2 00:06:66:ZZ:XX:YY"; #comando rfcomm para crear puerto

my $value;

if ($param eq "clean")
{#Si la orden es limpiar
    $value=135;    
}
elsif ($param eq "dock")
{#Si la orden es ir a base
    $value=143;
}
else
{#El resto no está aceptado
    die "$0 [CLEAN|DOCK]\n"; 
}

my $pid=open2 (\*READ,\*WRITE,$rfcomm); #lanzamos por un lado la conexión

sleep (10); #Le damos 10 segundos para que se establezca

system("stty -F $port 115200 raw -parenb -parodd cs8 -hupcl -cstopb clocal"); #Parámetros necesarios para configuración del puerto
    
my $roomba;
open $roomba, "+>$port" or die "couldn't open port: $!"; #Abrimos conexión al puerto
select $roomba; $| =1;  #Eliminamos lo que hubiera en el buffer en la lectura
    
printf $roomba "%c",128;  sleep 0.3;                    # START Necesario cada vez que le demos una orden a Roomba
printf $roomba "%c",132;  sleep 1;                    # FULL Tomamos control completo sobre ella

printf $roomba "%c",$value;  sleep 1;                    # CLEAN OR DOCK  Ejecutamos lo ordenado

kill 9,$pid; #Matamos el proceso de rfcomm

exit (0); #bye bye

Pero claro, la idea (al menos la mía) es hacer un programa que dependiendo de un montón de factores como qué horario es aceptable para pasar la aspiradora, control de presencia en casa (si estoy en casa, no la pases,… no sabéis el ruido que mete!), etc, etc,… puede ser interesante obtener información sobre los sensores de la misma. En mi caso, me interesa saber: La capacidad máxima de la batería; el modo de carga (esperando, cargando, etc,..), la carga actual de la batería, la temperatura de la batería, y si está conectada al cargador correctamente o no (si está en su base de carga o está dando vueltas por ahí). Para ello, el código se puede ver bajo estas líneas. Importante: en este caso contamos con una conexión rfcomm ya hecha en otro terminal!

[root@Carmen tmp]# more roomba_sensors.pl 
#!/usr/bin/perl

$port="/dev/rfcomm2";  #el puerto serie a crear. Importante que no esté siendo usado ya

system("stty -F $port 115200 raw -parenb -parodd cs8 -hupcl -cstopb clocal");  #Parámetros necesarios para configuración del puerto
    
my $roomba;

open $roomba, "+>$port" or die "couldn't open port: $!";
select $roomba; $| =1;   #Eliminamos lo que hubiera en el buffer en la lectura
    
printf $roomba "%c",128;  sleep 1;                    # START Necesario cada vez que le demos una orden a Roomba


printf $roomba "%c%c%c%c%c%c%c",149,5,21,25,26,34,24;  sleep 1; # Roomba requiere el envío del opcode 149 + el número de sensorIDs a solicitar + cada sensorID

#Sin embargo, devuelve byte a byte. Con esto perdí muuuucho tiempo porque no lo ví documentado en ningún sitio!!!
for ($i=0; $i<7; $i++) 
{
    $k=getc($roomba);
    $ok=ord ($k);
    print STDOUT "$i $ok\n";
}

Al ejecutarlo vemos algo como:

----------
0 2
1 1
2 108
3 10
4 136
5 2
6 40
------

La primera columna es un contador, sin más y la segunda, el valor del byte devuelto por la Roomba.

Byte        Explicación


0       Estado de carga: 4 significa que está en Waiting (aunque la pongamos en su base, no cargará)
         y 2 es Full charge (que lo podemos poner a cargar)
1       Byte más significativo de carga actual de batería
2       Byte menos significativo de carga actual de batería
3       Byte más significativo de capacidad total de batería
4       Byte menos significativo de capacidad total de batería
5       Presencia de cargador (Fundamentalmente, si está la roomba en su base o no) Si el valor es 0 es
         que no (está por ahí limpiando) y 2 es que está en la base
6       Temperatura en grados celsius de la batería (Interesante por si queremos monitorizarlo)


Los bytes 1 y 2, así como el 3 y 4 indican la carga actual y la capacidad máxima de carga de la batería. El byte más significativo, en mi caso va de 0 a 10 y el menos significativo va de 0 a 255 (lógicamente es lo que cabe en un byte). Cuando se está descargando la batería, los bytes 1 y 2 van disminuyendo y al cargarse aumentando, hasta llegar a 10/136 que es la carga máxima de la batería.

Conclusiones

Roomba no sé si me hará la vida más fácil o no, pero me lo he pasado bomba sacándole las tripas e intentandole hablar y que me conteste. No he encontrado foros en España (o al menos en español) en los que se haga hacking de este tipo a Roomba. Lo más aproximado ha sido en los foros.zackyfiles.com en los que fundamentalmente, se hace hacking físico a los equipos para que aspiren mejor, y hacerles cierto tunning. Los que quieran ir más allá, pueden contar con este foro en inglés  en el que hay gente con estas mismas inquietudes y en el que abrí un hilo pidiendo ayuda en mis problemas de comunicación con mi Roomba.
Para aquellos que tengáis un cacharro de estos y queráis meterle mano, os animo desde aquí a ello. Si os ponéis y se os atasca la situación, contad conmigo para ayudaros en todo lo que sea posible!

Por cierto, que después de tanta confianza que tengo con la Roomba, le he preguntado cuál es su blog de seguridad y hacking favorito y... bueno en la foto siguiente podéis ver cuál fue su respuesta :D

Leer más...

12 octubre 2009

¿Qué ocurriría si los robots se volvieran contra nosotros?

En InfoSec News hablaban de un artículo que trataba de lo peligroso que podría llegar a ser un robot, si fuera hackeado, si un atacante tomara el control; esto parecía sacado de una película de ciencia ficción.

Investigadores de la Universidad de Washington nos indican que se debe poner especial atención en la seguridad de los robots. ¿Qué ocurriría si llegaran a ser usados para espiarnos o realizar actos de vandalismo en nuestras casas?

Poco a poco los robots, se hacen un hueco en nuestras casas, robots aspiradora (iRobot's Roomba), Erector Spykee, RoboSapien y Rovio. Luchar como Sarah Conor en Terminator contra el RoboSapien suena divertido, pero no quiero imaginar los desperfectos que podría ocasionar.

Un profesor de la Universidad de Washington comenta que están alarmados por lo fácil que resulta a día de hoy comprometer la seguridad de algunos de estos robots. Su preocupación no es un futuro como en Terminator, sino un mundo en donde los hackers tomaran el control de los robots que circulan por nuestras casas.

Comenta, que algunos de estos robots son manejados vía WiFi y no sería difícil para un atacante situarse cerca y tomar el control del robot. Los robots Rovio pueden ser controlados desde Internet, por lo que un atacante que lograra obtener su usuario y contraseña podría controlar de forma remota el robot y usarlo como una máquina espía, podrían ver lo que hacemos y escuchar lo que decimos. También hablan sobre los posibles actos de vandalismo que pudieran realizar estos robots contra nosotros.

Pensemos en seguridad y privacidad desde el comienzo del diseño para que después no tengamos que estar aplicando parches cuando hayan ocurrido los desastres.
Leer más...