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

jueves, 22 de febrero de 2018

Montemos una IP-Webcam barata - Reloaded III

Este tema es inacabable. Después de todos los posts sobre la cámara IP a partir de una cámara usb y un router ADSL casero con OpenWRT/LEDE todavía me siguen saliendo cositas y ampliaciones cada pocos meses, así que no me queda otra opción que seguir revisitando el tema. Hagamos una retrospectiva:


Ahora el problema es que, recordemos, el guardado de las imágenes de captura se realizaba en una carpeta de un servidor remoto montada por sshfs. No es infrecuente que haya algún problema de red y esa conexión quede interrumpida. No siempre es restaurada esa conexión en tiempo y forma y a veces me encuentro con que llevamos varios días desechando imágenes ya que en el mermado espacio de almacenamiento del router ADSL no se puede guardar nada.

Para evitar esto he añadido código para que cuando se detecte que se ha perdido el montaje remoto por sshfs se envíe un correo especial de aviso, para que al menos pueda ponerle remedio cuanto antes. Marco en negrita la parte con el pequeño fragmento de código nuevo (el resto es como la ha ido quedando las últimas veces):
# cat /root/controlador.sh
#!/bin/ash

log() {
  test $montado -eq 1 && echo "$1" >> /mnt/snapshot/log.txt  
}

email() {
  test $email -eq 1 && echo -e "$1" | sendmail correo.aviso@gmail.com
}

monta_sshfs() {
  sshfs -o ssh_command="ssh -i /root/.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" -o nonempty openwrt@192.168.0.25:/home/openwrt /mnt
}

envia_secuencia() {

   if [ -e /tmp/motion.txt ]
   then

      #Recopila todos los ficheros de /tmp/motion/txt y los envia en un correo

      ficheros=$(cat /tmp/motion.txt | tr '\n' ' ')
      rm /tmp/motion.txt

      log "Historia de capturas $ficheros"
      zip -9 /mnt/escena.zip $ficheros

      echo "Secuencia $1" > /mnt/mensaje.txt
      test $email -eq 1 && mutt -s "Evento camara" correo.aviso@gmail.com -a /mnt/escena.zip < /mnt/mensaje.txt

      rm /mnt/escena.zip
      #Si no hay acceso al almacenamiento remoto, borramos las capturas para no llenar el disco del router.

      test $montado -eq 0 && rm -rf $destino

   fi

}

#Parametro 1: start, picture, end
#Parametro 2: fecha
#Parametro 3: nombre fichero (opcional)

#Obtenemos fecha y hora por si queremos poner algun filtro sobre ella y solo avisar en determinados
#momentos

time=$(date +%s)
anio=$(date +%Y @$time)
mes=$(date +%m @$time)
dia=$(date +%d @$time)
hora=$(date +%H @$time)
minuto=$(date +%M @$time)
diasemana=$(date +%u @$time) #El 1 es lunes
destino="/mnt/snapshot/$anio-$mes-$dia"
montado=1
email=0

if [ $diasemana -ge 6 -o $hora -le 7 -o $hora -ge 17 ]  # sabado/domingo o cualquier dia antes de las 8:00 o despues de las 17:00
then
   email=1
fi

#Si existe el fichero /mnt/testigo no se ha montado directorio remoto por sshfs,
#Intentamos montarlo y otra vez y luego preguntamos de nuevo.
#Si no se ha montado nada es que no se puede guardar nada de forma permanente ya que estamos escribiendo en la
#memoria interna del router y eso se llena rapido

test -e /mnt/testigo && monta_sshfs

if test -e /mnt/testigo
then
  #No está montado el directorio remoto, no hay donde guardar las imagenes
  montado=0
  #No hay almacenamiento por dias, no vamos a guardar tanto tiempo el fichero.
  destino="/mnt/snapshot"
  #Si no se ha avisado antes se avisa por correo
  if ! test -e /tmp/avisado
  then
     touch /tmp/avisado
     echo -e "Subject: Camara sin almacenamiento\r\n\r\nSe ha perdido la conexión remota con el directorio de almacenamiento de la cámara" | sendmail correo.aviso@gmail.com
  fi
else
  #Tenemos montado el directorio remoto, borramos el testigo de aviso.
  rm -f /tmp/avisado
fi

test -d $destino || mkdir -p $destino

case $1 in

  "start")
     log "Detectado inicio de movimiento $2" 
     email "Subject: Evento camara\r\n\r\nDetectado inicio de movimiento $2"
     #El fichero motion.txt tiene dos finalidades: 1) testigo para indicar que estamos detectando movimiento 
     #                                             2) guarda los nombres de los ficheros de captura de las fotos
     touch /tmp/motion.txt
     ;;
  "picture")
     fichero=$(basename $3)
     log "Guardando imagen $2 : $destino/$fichero" 

     #Si estamos en una ráfaga de movimiento detectado, guardamos el nombre de fichero con la foto.
     test -e /tmp/motion.txt && echo "$destino/$fichero" >> /tmp/motion.txt

     #Se guarda el fichero en el almacenamiento destino
     mv "$3" "$destino/$fichero"

     #Si no está montado el almacenamiento remoto y vemos que llevamos mas de 10 imagenes en
     #movimiento tenemos que borrarlas y enviarlas ya mismo, para no saturar el espacio.
     if [ $montado -eq 0 ]
     then
        #Si estamos en una ráfaga de movimiento detectado....
        if [ -e /tmp/motion.txt ]
        then
          lineas=$(wc -l /tmp/motion.txt | cut -d" " -f1)
          test $lineas -gt 10 && envia_secuencia $2
        else
          #Si no lo estamos, es una captura *snapshot* regular sin interés, la borramos.
          rm -f "$destino/$fichero"
        fi  
     fi
     ;;
  "end") 
     log "Detectado fin de movimiento $2"
     envia_secuencia $2
     ;;
   *) log "Evento $1"
esac


#Borra fichero "sent" creado por sendmail si existe, para liberar espacio
rm -rf /root/sent
rm -rf /sent
Para evitar enviar el mensaje en cada invocación del script se usa un fichero "avisado" en /tmp/ como bandera para verificar si se ha enviado o no ese mensaje. Ese fichero se borra cuando se detecta que se ha montado el directorio remoto o al reiniciar el equipo (todo el contenido de /tmp se borra en cada reinicio).

Bueno, pues seguro que vuelve la burra al trigo pronto y estamos otra vez aquí.



Hasta siempre Forges, me has hecho reírme de mí mismo muchas veces.

lunes, 19 de febrero de 2018

Ejecutar en los infolabs aplicaciones gráficas entrando con "ssh -X"

Esta mañana tenía que instalar Adobe Air y una aplicación .air remotamente en varios infolabs y como el instalador es "al estilo Windows" debía entrar por "ssh -X" y lanzar el ejecutable gráfico de instalación.

Me ha sorprendido bastante que fallase con el error de que no se podía abrir el display, como si no tuviera permisos para ejecutar aplicaciones X. La verdad es que nunca había tenido necesidad de ejecutar aplicaciones gráficas en remoto entrando por ssh en los infolab. He probado varias aplicaciones y en todas había problemas del tipo:
Failed to open display
o
Error: GDK_BACKEND does not match available displays
Lo primero ha sido mirar en /etc/ssh/sshd_config y ver que aparece:
X11Forwarding yes
Ante esto he quedado desconcertado un rato, hasta que he visto que ya lo solucionó mi compañero Manuel del IES Eugenio Hermoso. Hay que añadir a /etc/ssh/sshd_config la línea:
X11UseLocalHost no
Y reiniciar ssh en el infolab. ¡Gracias, Manolo!

¿Por qué esta línea no es necesaria en otros equipos como los Siatic y compañía? Pues no sabemos.

domingo, 18 de febrero de 2018

Windows: actualiza como puedas.

Vaya por delante que opino que usar Windows en un centro educativo es, salvo casos muy justificados, un disparate económico, ético y tecnológico. Pero por desgracia esa puerta quedó abierta en tiempos pasados y debemos lidiar con la situación como buenamente podamos.

1. Parte de guerra.

Una vez tienes instalados tus Windows "pelados" aparte de los problemas típicos de gestión de usuarios y administración te encuentras con la cuestión de sus actualizaciones, que tiene una idiosincrasia especial en un entorno como el nuestro. Repasemos:

Primero. Cualquier usuario, incluidos los defensores mas acérrimos, habrán comprobado que Windows tiene la irritante costumbre de actualizarse sin control y sin contemplaciones de forma extemporánea: al iniciar, al apagar o en medio de la operación de un PC. De una extraña manera, estas actualizaciones incluso no dudan en arrasar cuando les parece con el arranque dual haciendo desaparecer Linux del menú de arranque. Esto en mi opinión roza lo delictivo.

Segundo. Windows tiene un sistema de actualizaciones totalmente ilógico: si dejas un equipo sin actualizar 6 meses al lanzar el update no instala lo último, sino que pasa por casi toda la secuencia de actualizaciones que se han quedado atrás (pocas veces una actualización es descartada en favor de otra posterior), reiniciando el equipo varias veces. Eso, para la gente razonable acostumbrada a derivados de Debian y a las rolling relaease como mi querida Manjaro es sencillamente inconcebible. Me ha llegado a pasar que instalas un Windows 7 en una hora y luego te pasas 20 horas descargando actualizaciones por fases de descarga-instalación-reinicio hasta tenerlo al día.

Por otro lado, el proceso de actualización es tremendamente oscuro y nunca sabes que está pasando y si el sistema se ha quedado parado en alguna operación. Sabes cuando empieza y cuando acaba, pero no como avanza. Para los acostumbrados a la verbosidad de las actualizaciones en Linux este mutismo es incomprensible.

Tercero. Como ya avisamos en su momento a la gente que decide, para poner orden en este caos hace falta un sistema que nos permita administrar y dosificar el flujo de actualizaciones. Eso implica un Windows Server y un servicio WSUS por centro junto con el hardware para ello, lo cual representa un sensible gasto adicional en dinero y tiempo para administrarlo. Esto no se tuvo en cuenta por las mentes pensantes que decidieron adquirir licencias de Windows sin tino y nos dejaron el papelón a los de abajo.

También puedo hablar según mi experiencia: habiendo servido durante varios años en ICM, la antigua Agencia de Informática y Comunicaciones de la Comunidad de Madrid (muy conocida por colaborar con las tramas corruptas Púnica y Lezo; tranquilos: yo soy inocente, todo eso pasó mayormente mientras estaba de excedencia) donde todo se basaba en Windows. Incluso con toda la infraestructura de clientes y servidores Windows montada para gestionar las actualizaciones de forma controlada los problemas en los clientes eran constantes: parches que se enrocaban en una instalación iniciada e interrumpida infinitamente, equipos en que fallaba algo y se quedaban atrás sin actualizar, errores y pantallazos azules en arranques tras actualizaciones fallidas... y todo esto con Windows XP, en los que el que ritmo de actualizaciones era mucho mas reducido que en los Windows posteriores.

Cuarto. Para mas INRI, esto último no sirve nada tan pronto como comprendes la realidad de funcionamiento de los PC de los centros educativos. Esto no es una oficina al uso donde los PC se encienden de 8 a 15 o de 9 a 17. Un PC en un centro educativo se enciende y se apaga de forma aleatoria a lo largo del día según el uso en las materias y horarios de clase. Incluso podemos encontrarnos con PC que no se encienden durante muchos días y de repente luego se encienden una mañana entera con 3 reinicios al cambiar de clase. Evidentemente disparar unas actualizaciones que pueden tardar horas en un entorno tan aleatorio es un proceso abocado a la catástrofe: tanto por el consumo de ancho de banda que se incrementa de golpe al encender un grupo de PC de alumnos, así como por el ralentizamiento del PC asociado a la actualización y los problemas derivados de apagarlos cuando están a medias.

Cinco. Podríamos pensar que los PC de uso de los profesores (salas comunes, aulas, departamentos) si que están encendidos de forma continua. Falso: son ordenadores de uso compartido y una de las pequeñas luchas que tenemos los administradores informáticos es limitar la pulsión que tienen muchos usuarios de apagar el sistema operativo cuando se acaba su sesión, máxime teniendo en cuenta que en 5 minutos va a haber otro docente sentado en ese mismo sitio. Pues bien: no hay manera, cuando alguien quiere apagar, apaga.

Seis. ¿Puede empeorar la cosa? Si: las aulas de portátiles. Nada mas terrible que ir a guardar un portátil en un armario de carga porque acaba la clase y encontrarnos que nos dice que esperemos porque hay que instalar 13 actualizaciones. O encenderlo para empezar la clase y esperar 10 minutos a que se actualice. Pero eso no es todo: tenemos 20 portátiles conectados a un punto de acceso wifi normal y corriente pugnando por actualizar, descargando megas y megas cada uno e impidiendo el uso normal de todos los dispositivos conectados a la misma wifi. Como seguramente en una hora de clase no de tiempo a descargar todo en la próxima sesión volveremos a la casilla de salida.


2. Estrategias paliativas.

Ante este panorama no nos queda otra que lidiar como buenamente podamos con todo ello. Si quedamos las actualizaciones a su libre albedrío la tragedia en forma de sistemas dañados por el apagado en medio de una actualización o redes colapsadas está garantizada. Parafraseando el proverbio chino: simplemente tenemos que sentarnos a la orilla del río y esperar hasta que pasen los Windows muertos flotando corriente abajo. El problema es que al final esos Windows tenemos que resucitarlos nosotros.

En mi caso he optado por dos estrategias para evitar la debacle:

  1. Cuando es posible por la potencia del equipo cliente virtualizo los Windows y los dejo con las actualizaciones desactivadas. Tengo un master que actualizo de vez en cuando en un PC concreto y distribuyo luego el fichero .VDI (imagen del disco duro) a todos los demás.
  2. Si no es posible virtualizar, porque los PC andan justitos de procesador y memoria opto por dejar un arranque dual y: desactivar en la medida de lo posible las actualizaciones automáticas de Windows, usar un sistema basado en wsusoffline, como recomienda nuestro compañero Esteban, para actualizar contra un repositorio interno al IES y no contra Internet (con lo cual ahorramos tráfico de red) y cada cierto tiempo me toca perder varios días actualizando semi-manualmente los equipos.

Vamos a ver esto con detalle.

3. Parar, reanudar y limitar las actualizaciones.

No es plato de buen gusto parar las actualizaciones de un PC, se supone que incluyen mejoras y parches contra agujeros de seguridad como Wannacry, Meltdown o Spectre. Pero cuando la alternativa es tener el aula parada y los usuarios malhumorados porque todo el tiempo y ancho de banda se va en actualizar dices "¡pero que coño!" y paras todo.

La forma más efectiva que he encontrado de parar las actualizaciones automáticas es con estos comandos que se pueden meter en un script:
sc config wuauserv start= disabled
net stop wuauserv
reg add HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU  /v NoAutoUpdate /t REG_DWORD /d 1 /f
Con esto el Windows queda congelado en el tiempo salvo que Microsoft use algún truco artero para colarnos algo, tal como hace con esas instalaciones de Cortana u OneDrive que reaparecen después de haberlos eliminado una y otra vez. Si queremos volver a activar haremos los pasos contrarios:
sc config wuauserv start= auto
net start wuauserv
reg add HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU  /v NoAutoUpdate /t REG_DWORD /d 0 /f
Otra opción que puede resultar interesante es usar una característica que tiene Windows de definir una conexión inalámbrica de red como "metered" o de uso medido. Eso viene a significar que le avisamos de que esa conexión nos cuesta dinero cada megabyte y que por tanto, tenga ojito con lo que se descarga por ella. Pensemos por ejemplo en una conexión móvil 4G, un operador de wifi o el futuro Starlink de Elon Musk, que nos facturase por datos transferidos.

Para ello debemos establecer la conexión a la red y una vez hecha tecleamos:
netsh wlan show profiles
Esto nos mostrará el nombre de la conexiones wlan (redes wifi o 4G), por ejemplo algo así como "Airtel-WRTR301GN-8897_1". Una vez sabido el nombre, con:
netsh wlan show profile name="Airtel-WRTR301GN-8897_1"
Vemos los parámetros de la conexió. En ellos el parámetro "Cost" puede valer Unrestricted (no limitado) o Fixed (limitado). Por tanto, si queremos indicar que la conexión es metered hacemos:
netsh wlan set profileparameter name=”Airtel-WRTR301GN-8897_1″ cost=Fixed
Esto hará que Windows se lo piense antes de consumir ancho de banda en una actualización por esa conexión. Pero, ojo, esto no descarta todas las actualizaciones y las que se consideren críticas se realizarán. Aunque está concebido para conexiones inalámbricas, también podemos activarlo en conexiones cableadas trasteando el registro.

4. Encauzar las actualizaciones con WSUS Offline Update.

WSUS Offline Update es un sistema montado para realizar las actualizaciones de los Windows/Office usando la red local y minimizando el tráfico externo. Incluso permite actualizar Windows/Office sin conexión a Internet, descargando las actualizaciones a un pendrive y actualizando luego con él. Yo lo descubrí, como tantas otras cosas, gracias a mi compañero Esteban.

Todo rota en torno a 3 elementos:

  • Una aplicación/script que descarga las actualizaciones y parches disponibles para los sistemas seleccionados.
  • Un repositorio donde guardar lo descargado. Traduciendo: una carpeta local o de red donde guardar los archivos.
  • Una aplicación/script que examina el sistema Windows y actualiza con los parches pendientes.

Una visión detallada del sistema la podemos encontrar aquí.

En mi caso no he usado las aplicaciones gráficas para realizar las tareas, ya que como se deducirá me va mas la línea de comandos. Además he intentado que las dos primeras partes se realicen con Linux y un servidor samba. Solo la parte de aplicación de las actualizaciones es, evidentemente, sobre Windows. Para ello me he guiado por este manual.

En un servidor auxiliar creo una carpeta /datos/wsus, con permisos 777 para todo su contenido. Sobre esa carpeta descomprimo la última versión de wsusoffline, que a fecha de escribir este post es la 11.1.1.

Una vez descomprimido el .zip escribo el script que me hará la descarga de los parches y actualizaciones para los sistemas que le indique:
# cat /datos/wsus/update.sh
bash /datos/wsus/wsusoffline/sh/download-updates.bash w100 esn /includedotnet /includemsse /includewddefs /verify
bash /datos/wsus/wsusoffline/sh/download-updates.bash w63-x64  esn /includedotnet /includemsse /includewddefs /verify
bash /datos/wsus/wsusoffline/sh/download-updates.bash w100-x64 esn /includedotnet /includemsse /includewddefs /verify
# chmod +x datos/wsus/update.sh
Este script descarga lo que haya de Windows 10 (64 y 32 bits) y Windows 8 (64 bits). Mirar la documentación para ver todas las posibles opciones de descarga (Windows 7, Office, Visual C++, .NET, ...). Lanzamos la ejecución del script y nos vamos a hacer otras cosas, porque tarda un rato en descargar todo:
# /datos/wsus/update.sh
Cuando termina, vemos que ha hecho:
# du -sh /datos/wsus/wsusoffline/client
2,6G w100
4,8G w100-x64
1,9G w63-x64
# ls -1 /datos/wsus/wsusoffline/client/w100-x64/glb/
windows10.0-kb3172729-x64_bb12a14ec3891ec0a9e24edb529632263783d389.cab
windows10.0-kb3172729-x64_f4fc9775baa98c176f43e87c40088231a884122b.cab
windows10.0-kb3173427-x64_d95e56e499e2c281a1f59585221dc891253414c7.cab
windows10.0-kb3173427-x64_e3da65fe753d24a1759cdd029028cde743a62a23.msu
windows10.0-kb3173428-x64_52fa3686737353fae20ab55fa9c924bd90558a31.cab
windows10.0-kb4035632-x64_ea26f11d518e5e363fe9681b290a56a6afe15a81.msu
windows10.0-kb4049011-x64_a58e4c340939a7b23b86055a18abdc9c59308094.msu
windows10.0-kb4049065-x64_f92abbe03d011154d52cf13be7fb60e2c6feb35b.msu
windows10.0-kb4056887-x64_0fcf1ff448cea9474ea089a3d866beeb7212cec1.cab
windows10.0-kb4056887-x64_12a57a1104466ca878eb096fefa6c6babe520810.cab
windows10.0-kb4056887-x64_1e5c03724988979684c35a5493829e4abe9bdbfc.cab
windows10.0-kb4056887-x64_57d92c622280f34d0ee271a9c58fdce91c3c6808.cab
windows10.0-kb4056887-x64_8ad98c5fb14f2938536d794074a5b901b6eb0d72.cab
windows10.0-kb4056888-x64_5943823d032a25e40f8eee1613aa849d3963bd1d.cab
windows10.0-kb4056890-x64_2d0216b0e6b49f457e5111fbd7d766984af3f6cf.cab
windows10.0-kb4056891-x64_99b9dadbd6a71c8c9ca58b8e53285f8320dd32e3.cab
windows10.0-kb4056892-x64_39198b373a07390a3afdf2a64d19f24d59fca7a6.cab
windows10.0-kb4056893-x64_f025805bafd32c5f9d7ca37eb255a894dfb025d8.cab
windows10.0-kb4058702-x64_4ed8d0df4f3c190d3e423bf287d7e95a21a9124a.msu
Y ahí vemos todos los ficheros con las distintas actualizaciones y parches descargados esperando para ser aplicados según necesite el cliente Windows. Este script lo ejecutaremos de vez en cuando o al menos cuando se actualice wsusoffline.

Estos ficheros hay que compartirlos usando una carpeta samba de solo lectura accesible desde los Windows:
# cat /etc/samba/smb.conf
...
...
[wsus]
comment = WSUS Windows Updates
path = /datos/wsus
writable = no
browseable = yes
guest ok = yes
force directory mode = 0777
...
...
Reiniciamos samba y desde un Windows podemos abrir una ventana de comandos con credendiales de usuario administrador y teclear:
net use z: \\ip-servidor\wsus /persistent:no
Z:\wsusoffline\client\cmd\DoUpdate.cmd
Con lo cual empezará el laaaargo proceso de actualizaciones, que puede durar varias horas. En la ventana de terminal nos va informando escuetamente de cada parche aplicado. No nos desanimemos: si fuese mediante actualizaciones online podría tardar varios días y saturar la conexión de red del centro. De esta manera al menos tenemos controlado lo que se va haciendo y que se va actualizando.

5. Cosas a tener en cuenta.

Esto no es un camino de rosas, simplemente es algo para aminorar los problemas. Por eso debemos tener en cuenta varias cosas:

  • El wsusoffline es el sistema mas rápido si tenemos varios PC con Windows y el que menos tráfico de red genera, pero va siempre desactualizado respecto a los repositorios oficiales. Hay que vigilar si hay versiones nuevas de vez en cuando para actualizalo. A fecha de escribir esto la última actualización descargada es KB4058702, pero en Microsoft van por la KB4074608, que además es incompatible con la anterior, lo cual puede causar problemas en el script.
  • El update mas fiable es el realizado online contra los repositorios de Microsoft. El problema es que puede tardar mucho tiempo, descargar varios gigas y exigir varios reinicios. Multiplica eso por el número de Windows de tu red. De todas formas, si no nos queda otro remedio que hacerlo para salir de alguna situación complicada podemos abrir de forma directa la ventana para actualizaciones haciendo en un intérprete de comandos de Windows:
    C:\Windows\System32\control.exe /name Microsoft.WindowsUpdate 
    
  • Una alternativa a lo anterior o un método para salir de un atasco en que todas las actualizaciones fallan porque hay que subir de versión (por ejemplo, pasar de la 1703 a la 1709 en Windows 10) es descargar la última ISO de Windows (a día de hoy la 1709), montarla con wincdemu y actualizar desde allí.

Después de todas estas actualizaciones es bueno saber en que versión tenemos el Windows. Por ahí se comenta que ejecutando en una consola Powershell:
Get-CimInstance Win32_OperatingSystem | Select-Object buildnumber,version
Se muestra la versión, pero es falso ya que no sale completo todo el número de compilación. La manera de saberlo es con:
winver
Nos muestra:


Este Windows tiene por tanto en el momento en que escribimos esto la versión 1709, compilación 16299.192. Esta bastante actualizado a día de hoy, si buscamos en internet el "Historial de actualizaciones de Windows 10" vemos:


Podemos ver que nuestro Windows está en la compilación .192 y según la página de Microsoft posteriormente "sólo" han salido la 201, 214 y la 248. Cuando empecé a elaborar esta entrada ibamos por la 214 y ya ha salido otra, ahí es nada. Es verlo y me da la bajona... vaya cruz.

jueves, 8 de febrero de 2018

Acceso directo una camara IP Dlink DCS-5000L.

Tenemos una cámara IP DCS-5000L que cumple todas las expectativas de un dispositivo de este tipo: interface web, acceso y control remoto (mediante un motor para girar el objetivo), grabación, detección y aviso de movimiento y/o sonido, visión nocturna....

Además de esto echaba en falta poder acceder desde fuera, con programas mas potentes y versátiles como motion (que ya usamos con OpenWrt anteriormente) o su estupendo frontend para videovigilancia motionEye.

Ya puestos en tarea, por su buena calidad de imagen veía interesante usarla poder usar para videoconferencias o emisiones de vídeo grupales, con Google Hangouts, Skype o similares.

Por todo ello vamos a tratar en este post como conectarnos a ella con aplicaciones diferentes al tradicional navegador e ir probando cosas a ver hasta donde llegamos.

1) Acceso directo al stream de vídeo/audio.

Lo primero es acceder a las imágenes y audios de forma directa, sin pasar por el interface web, el cual tiene este aspecto:


Como vemos la visualización de las imágenes está basada en tecnologías rabiosamente nuevas como Flash, Java y ActiveX. El interface permite ver, oír, mover la cámara y acceder a su configuración.

Normalmente en foros no oficiales aparecen las URL de acceso directo a los streams de audio y vídeo de las cámaras IP de Dlink, pero para esta webcam no había manera de encontrarlos. Afortunadamente mi buen compañero David usó sus oscuras artes de teleco para llegar a acceder y pasarme esto:

  • Foto: http://192.168.0.112:8080/image/jpeg.cgi. Descarga un jpg con una foto fija tomada de forma instántanea con la cámara. Podemos tomarla con :
    wget -O imagen.jpg http://192.168.0.112:8080/image/jpeg.cgi
  • Vídeo: http://192.168.0.112:8080/video.cgi. Emite un stream de vídeo en tiempo real con formato MJPEG y resolución de 640x480 píxeles. Podemos verlo con:
    vlc http://192.168.0.112:8080/video.cgi
  • Audio: http://192.168.0.112:8080/audio.cgi. Si hemos activado el audio en la cámara y subido el volumen del micro lo suficiente accederemos al stream de audio del micrófono. Nos llega como un wav en formato PCM de 16bits de frecuencia 11025Hz. Podemos oírlo en directo con:
    vlc http://192.168.0.112:8080/audio.cgi
De esta manera podríamos monitorizar la cámara con motion usando el parámetro netcam_url:
# cat /etc/motion/motion.conf:
.....
.....
netcam_url http://192.168.0.112:8080/video.cgi
.....
.....
Como vemos aparte de acceder a cámaras locales, motion permite controlar cámaras de red. Incluso podríamos hacer cosas mas interesantes, como activar la grabación de sonido ante un evento detección de movimiento.

2) Reproducción en ventana independiente y grabación.

El siguiente paso es ver si podemos reproducir el flujo de vídeo en una ventana independiente usando esa navaja suiza de los streams multimedia que es gst-launch.

Empecemos con:
gst-launch-1.0  souphttpsrc location=http://192.168.0.112:8080/video.cgi ! jpegdec ! autovideosink
Básicamente cogemos el stream remoto, lo pasamos por el plugin "jpegdec" que decodifica los fotogramas jpeg que forman la imagen y lo volcamos en el sink (un sink es un sumidero donde acaba el stream tras pasar por los plugins) autovideosink, que muestra el vídeo con una fluidez estupenda en una ventana independiente tal que así:


De esta manera logramos ver la cámara en directo prescindiendo de Flash, Java y demás puñetas anteriores al Holoceno.

Gstreamer tiene plugins y filtros de todo tipo, como por ejemplo este para girar la imagen 90º:
gst-launch-1.0  souphttpsrc location=http://192.168.0.112:8080/video.cgi ! jpegdec ! videoflip method=clockwise ! autovideosink
Aquí tenemos varios ejemplos más. Estos son todos los plugins y sinks aplicables.

Ahora vamos a por el stream de audio. Por ejemplo, veremos como grabar el audio a un fichero, primero con mplayer:
mplayer http://192.168.0.112:8080/audio.cgi  -ao pcm:file=/tmp/mystream.wav -vc dummy
Y ahora con gst-launch:
gst-launch-1.0 souphttpsrc location=http://192.168.0.112:8080/audio.cgi ! filesink location=/tmp/mystream.wav
Ahora oímos el sonido en directo (ojo, si estamos en la misma habitación el sonido acaba acoplándose con un chirrido irritante), como si fuese un micrófono espía :
gst-launch-1.0 souphttpsrc location=http://192.168.0.112:8080/audio.cgi ! wavparse ! autoaudiosink
Lo mismo, pero reproduciendo el sonido por pulseaudio:
gst-launch-1.0 souphttpsrc location=http://192.168.0.112:8080/audio.cgi ! wavparse ! pulsesink 
Ahora juntamos ambos streams (audio y vídeo) para reproducirlos a la vez:
gst-launch-1.0  souphttpsrc location=http://192.168.0.112:8080/video.cgi ! jpegdec ! autovideosink  souphttpsrc location=http://192.168.0.112:8080/audio.cgi ! wavparse ! autoaudiosink
Si hacemos pruebas veremos que el audio va con un retraso de varios segundos respecto al vídeo. Después de varias pruebas concluyo que es algo ineludible, tiene pinta de ser una feature de la cámara.

3) Vídeo remoto como local: dispositivo /dev/videoX y loopback.

Vamos un paso mas allá: ¿y si queremos usar la cámara para una aplicación de videoconferencia, tipo Skype o Hangouts? ¿Y si queremos hacer una captura del vídeo para algún tipo de procesado con cheese? Estas aplicaciones no trabajan con cámaras remotas, sino que lo hacen con dispositivos físicos /dev/videoX creados al conectar una fuente de vídeo USB o PCI.

¿Podemos hacer que la cámara IP sea accedida en /dev/videoX como una local? Pues sí, Linux es maravilloso. Todo pasa por crear un dispositivo de vídeo virtual, que hará aparecer un /dev/videoX y luego podremos conectar el stream de vídeo de la cámara a dicho dispositivo. Esto se consigue con el driver v4l2loopback.

Para Ubuntu 14.04 ésta es la versión ya compilada (para Manjaro/Arch sería ésta). Los pasos para descargarlo y cargar en memoria el módulo son:
# wget https://launchpad.net/ubuntu/+archive/primary/+files/v4l2loopback-dkms_0.10.0-1_all.deb
# apt-get install v4l-utils
# dpkg -i v4l2loopback-dkms_0.10.0-1_all.deb
# rmmod v4l2loopback
# modprobe v4l2loopback -r
# modprobe v4l2loopback devices=1 exclusive_caps=1 video_nr=1 card_label="virtualvideo1"
Con esto se carga el módulo v4l2loopback en memoria y se crea un dispositivo virtual /dev/video1. Podemos comprobarlo con:
# v4l2-ctl --list-devices
De momento este dispositivo está vacío. Si abrimos vlc o cheese leyendo de él no se muestra nada. Hay que conectar el stream remoto de la cámara con el módulo v4l2loopback, el cual a su vez lo hará emerger por /dev/video1.

Esto lo hacemos con gst-launch usando el sink "v4l2sink" para enviar los datos a /dev/video1:
gst-launch-1.0  souphttpsrc location=http://192.168.0.112:8080/video.cgi ! jpegdec ! tee ! v4l2sink device=/dev/video1 sync=false
O también podemos usar ffmpeg (en ubuntu se instala antes desde un PPA).
ffmpeg -re -f mjpeg -i http://192.168.0.112:8080/video.cgi  -f v4l2 -vcodec rawvideo -pix_fmt yuv420p /dev/video1
En las pruebas realizadas con Google Hangouts, usando ffmepg la transmisión de vídeo hacia el dispositivo virtual y al cliente remoto es más fiable, estable y fluida que con gst-launch. Recomendamos por tanto usar ffmpeg sobre gst-launch para enviar el stream de la cámara al dispositivo v4l2loopback.

Para ampliar, aquí tenemos documentados varios métodos de enviar fuentes de vídeo a v4l2loopback.

Una vez creado /dev/video1 estas son las pruebas que he hecho:
  • Con vlc leyendo de /dev/video1 ("vlc v4l2:///dev/video1") la imagen se ve sin problemas.
  • Con cheese no funciona a la primera, pero quitando "exclusive_caps=1" al cargar el módulo si funciona.


  • Con Google Hangouts: he tenido problemas (no detección de la cámara) según la versión de Google Chrome y Firefox. En Chromium si ha funciona correctamente.


  • Con Skype: no lo he probado por los problemas que da con Linux últimamente, pero debe funcionar según el enlace comentado anteriormente.

Resumiendo: podemos usar la cámara IP cómo si fuera una cámara local, tanto para programas de captura de vídeo tipo cheese como para una videoconferencia con Hangouts o Skype. Las ventajas son:
  • Tiene mejor calidad que una cámara USB normal.
  • Puede colocarse en sitios que permiten tomas panorámicas para videconferencias grupales.
  • Conectados al interfaz web estándar de la webcam podemos girar/mover la cámara remotamente durante la emisión.




4) Videoconferencia con sonido.

El módulo v4l2loopback transmite vídeo, pero no sonido. En el apartado 1 y 2 hemos oído el sonido remoto recogido por la cámara en el PC local, pero para videconferencias habría que tratar el sonido remoto como una fuente de sonido (vamos, que el sistema vea el stream entrante como un micrófono). Después de varias pruebas con pulsesink y distintas configuraciones de pulseaudio según este ejemplo se consigue conectar el audio remoto con ciertas aplicaciones:

gst-launch-1.0 souphttpsrc location=http://192.168.0.112:8080/audio.cgi ! wavparse ! pulsesink 

En este ejemplo anterior redirigimos el sonido del stream por la tarjeta HDMI y luego emerge en los Dispositivos de Salida, permitiendo realizar una grabación con un tercer programa (un grabador de audio en nuestro caso).

¿Esto podría usarse para videoconferencias? En teoría si, en la práctica no porque los programas de videoconferencia que he probado solo aceptan entrada de sonido de micrófonos reales, no de streams que provienen de una fuente remota o de un "monitor of ..." en pulseaudio.

Seguramente hay una manera de convertir el stream en un micrófono virtual (como hicimos con el vídeo y /dev/videoX) encadenando módulos loobpacks y null de pulseaudio, o como se comenta en diversos foros usando jackaudio , pero realmente no merece la pena. El sonido de la cámara llega con tanto retraso que desmerece el conjunto y hace vano el esfuerzo.

Mi conclusión es que es mucho más cómodo usar un micro local estándar conectado al PC desde donde hacemos la videoconferencia, de tal manera que el vídeo proviene de la cámara mediante v4l2loopback, pero el audio se recoge de forma directa por el PC, despreciando el stream de audio que genera la cámara.

Aquí una captura de pantalla de una videoconferencia de Google Hangouts mediante Chromium Browser. La imagen "ojo de pez" es la imagen de la cámara web y el sonido se recoge con un micro normal y corriente.


En la parte inferior derecha en pequeñito está la imagen tomada por el receptor, que es un móvil apuntando a la cámara web :-).

Otra imagen usando visión nocturna:


Recordemos, como dijimos en el anterior apartado, que para videoconferencias con Hangouts da mucho mejor resultado usar ffmpeg (y no gst-launch) para enviar el flujo de vídeo a v4l2loopback.

5) Emisión RTSP.

Por último, también puede ser interesante usar los streams de audio y vídeo para crear una emisión RTSP emitiendo por la red lo capturado por la cámara de forma que cualquier receptor pueda "sintonizarnos".

Esto son solo varias pinceladas para abrir las posibles vías de prueba:
  • Usando v4l2rtspserver: al parecer genera una emisión rtsp a partir de un dispositivo v4l2 (como v4l2loopback) y una fuente de sonido. Los paquetes .deb están aquí. Ademas necesita v4ltools, que hay que compilar a mano.
    El github de Michel Promonet, de donde viene esto, tiene varios proyectos muy interesantes para la emisión de vídeo.
  • Usando gstreamer: por desgracia gst-launch por si solo no es capaz de redigir el vídeo hacia rtsp. Existe una solución de pago en la que se usa un sink llamado gstrtspsink que es a su vez un servidor rtsp. Podemos pedirles una versión de evaluación.
  • Usando gstreamer para emisión rtp, mas sencilla que la de rtsp:
    # gst-launch-1.0 souphttpsrc location=http://192.168.0.112:8080/video.cgi !  jpegdec ! rndbuffersize max=1316 min=1316  ! udpsink host=127.0.0.1 port=5000  
    
    Para la recepción hace falta un fichero .sdp, pero no le he dedicado mucho tiempo a hacerlo funcionar.
  • Usando una utilidad específica para montar un rtsp server: el problema es que la mayoría son sistemas profesionales de pago (por poner un ejemplo: este o este otro). He encontrado algo sencillo y gratuito hecho en perl. Compilamos según las instrucciones y arrancamos el servidor:
    # /usr/local/share/perl/5.18.2/RTSP/rtsp-server.pl
    Arrancamos la fuente de vídeo/audio:
    # ffmpeg -re -f mjpeg -i http://192.168.0.112:8080/video.cgi -i http://192.168.0.112:8080/audio.cgi -f rtsp  -muxdelay 0.1 rtsp://127.0.0.1:5545/abc
    
    La recepción se haría:
    # vlc rtsp://127.0.0.1/abc
    En las pruebas realizadas la emisión se ve pixelada y el audio viene con retraso. Utilizando audio con micro local y jugando con parámetros de ffmpeg seguramente se pueda mejorar.
  • Usando ffserver, una herramienta más de la suite FFmpeg. Tomamos este texto como guía:
    # cat /etc/ffserver.conf
    
    Port 8090
    BindAddress 0.0.0.0
    MaxClients 1000
    MaxBandwidth 10000         
    
    <feed feed1.ffm>
    File /tmp/feed1.ffm
    FileMaxSize 5M
    </Feed>
    
    <stream camara1.avi>
    Feed feed1.ffm
    Format mpjpeg
    VideoFrameRate 25
    VideoIntraOnly
    VideoSize 640x480
    NoAudio
    Strict -1
    </Stream>
    
    <stream stat.html>
    Format status
    </Stream>
    
    Arrancamos el servidor:
    # ffmpeg -re -f mjpeg -i http://192.168.0.112:8080/video.cgi  http://localhost:8090/feed1.ffm
    
    La recepción se haría en la URL:
    http://localhost:8090/camara1.avi
    Esto es sin sonido, para añadir audio debemos emitir en formato .webm.
    # cat /etc/ffserver.conf
    
    Port 8090
    BindAddress 0.0.0.0
    MaxClients 1000
    MaxBandwidth 10000         
    
    <feed feed1.ffm>
    File /tmp/feed1.ffm
    FileMaxSize 5M
    </Feed>
    
    <stream camara1.flv>
    Feed feed1.ffm
    Format webm
    
    # Audio settings
    AudioCodec vorbis
    AudioBitRate 64          # Audio bitrate
    
    # Video settings
    VideoCodec libvpx
    VideoSize 640x480        # Video resolution
    VideoFrameRate 25        # Video FPS
    AVOptionVideo flags +global_header  # Parameters passed to encoder
    # (same as ffmpeg command-line parameters)
    cpu-used 0
    AVOptionVideo qmin 10
    AVOptionVideo qmax 42
    AVOptionVideo quality good
    AVOptionAudio flags +global_header
    PreRoll 15
    StartSendOnKey
    VideoBitRate 400         # Video bitrate
    
    </Stream>         
    
    <stream stat.html>
    Format status
    </Stream>
    
    Empezamos emisión:
    # ffmpeg -re -f mjpeg -i http://192.168.0.112:8080/video.cgi -i  http://192.168.0.112:8080/audio.cgi
    
    Y conectamos con el navegador:
    http://localhost:8090/feed1.ffm
    Como antes, se ve pixelado y con el audio retrasado. La solución sería la planteada en su momento: audio local con micrófono y ajuste de opciones de ffmpeg.

Hasta aquí todo por ahora, creo que le hemos sacado a la cámara todo el jugo que le podíamos sacar.

No puedo evitar despedirme con una de las imágenes mas emocionantes de los últimos años: los dos side boosters del Falcon Heavy de SpaceX aterrizando al unísono:


Gracias Elon y buen viaje a Starman en su Tesla hacia la órbita de Marte.



martes, 30 de enero de 2018

Instalación de una aplicación mediante wine para todos los usuarios.

Hace poco me pidieron instalar la aplicación PhotoFiltre en Ubuntu ya que necesitaban usar una aplicación sencilla de retoque fotográfico. Solo tiene versión Windows, pero tras descargar el instalador y lanzarlo con wine confirmé que era totalmente funcional.

El problema que tiene wine es que la instalación de las aplicaciones va asociada al usuario, lo cual me obligaría a instalar la misma aplicación una y otra vez en todas las cuentas necesarias. En este caso la única molestia es el tiempo perdido apretando una y otra vez la misma tuerca, pero en aplicaciones que ocupan mucho espacio tenemos además el problema del disco desperdiciado con instalaciones idénticas en el home de cada alumno/profesor.

Según recuerdo con Codeweavers Crossover podías hacer una sola instalación de una aplicación Windows en una bottle (wine->bottle, son unos cachondos) y reusar luego esa bottle en distintas cuentas de usuario. Pero Crossover es de pago y yo tengo que usar wine de forma gratuita.

Así que buscando una manera de hacer una única instalación por máquina encuentro ésto y pruebo a ponerlo en práctica:

Creamos un usuario "windows" local con home en /var/home (para no interferir con nuestro /home en NFS):
# adduser --home /var/home/windows windows
Hago login con el nuevo usuario, descargo el PhotoFiltre y los ficheros de idioma español y los instalo con:
$ wine pf7-setup-en-7.2.1.exe
Después instalo el idioma español copiando el fichero según comentan en la página del programa.

El programa se ha instalado como es normal en wine, en la ruta:
/var/home/windows/.wine/drive_c/Program\ Files\ \(x86\)/PhotoFiltre\ 7/
habiéndose creado un acceso directo en el escritorio del usuario "windows". Si lo lanzamos desde dicho acceso directo se abre y funciona sin problema.

El reto está en hacer que funcione para los otros usuarios de la máquina sin tener que volver a instalarlo. Para ellos vamos a hacer uso de "sudo", que nos permitirá adoptar la identidad del usuario "windows" y ejecutar el programa desde otras sesiones de usuario. Empezamos tocando en el fichero sudoers:
# cat /etc/sudoers
..........
..........
# Configuracion Wine:
User_Alias WINDOWS_USERS = %teachers
Cmnd_Alias WINDOWS = /usr/bin/wine,/usr/bin/winecfg,/var/home/windows/pf7

Defaults:WINDOWS_USERS env_reset
Defaults:WINDOWS_USERS env_keep += DISPLAY
Defaults:WINDOWS_USERS env_keep += XAUTHORITY

WINDOWS_USERS ALL = (windows) NOPASSWD: WINDOWS

En este sudoers damos permisos a todos los usuarios del grupo "teachers" (aquí especificaremos los usuarios o grupo de usuario que queramos) a ejecutar wine, winecfg y el script /var/home/windows/pf7 con la identidad del usuario "windows". El contenido del script pf7 sería:
# cat /var/home/windows/pf7
#!/bin/bash
env WINEPREFIX="/var/home/windows/.wine" wine C:\\Program\ Files\ \(x86\)\\PhotoFiltre\ 7\\PhotoFiltre7.exe
exit 0
Lo que hace es fijar un WINEPREFIX en el directorio donde está wine y lanzar el ejecutable. Esta ruta está sacada del interior archivo .desktop que comentamoss anteriormente, creado por la aplicación en el escritorio durante su instalación con wine.

Ahora tenemos que establecer el medio para que los otros usuarios arranquen el script /var/home/windows/pf7 con la identidad del usuario "windows". Para ello definimos un nuevo script en una carpeta accesible para todo el mundo:
# cat /usr/bin/pf7
#!/bin/bash
xhost +
sudo -u windows -H /var/home/windows/pf7
exit 0
En él ponemos "xhost +" para permitir al usuario "windows" abrir aplicaciones dentro de nuestra sesión Xorg y hacemos el "sudo .../var/home/windows/pf7" para ejecutar el programa con la identidad "windows" sin que nos pida contraseña alguna.

Por último nos hace falta un fichero .desktop para poner en el escritorio de los usuario que vayan a ejecutar la aplicación:
# cat PhotoFiltre7.desktop
[Desktop Entry]
Name=PhotoFiltre 7
Exec=/usr/bin/pf7
Type=Application
StartupNotify=true
Path=/usr/bin
Icon=/usr/share/icons/hicolor/pf7.png
El icono /usr/share/icons/hicolor/pf7.png lo he extraido del .EXE con la aplicacion wrestool:
# wrestool -x fichero.exe -o .
Ultimando las cosas hemos creado una carpeta /wine con propietario "windows" y mapeado z: y "Mis Documentos" sobre ella usando winecfg con la cuenta "windows". De esta manera la aplicación podrá guardar sus datos en una carpeta accesible y fácil de encontrar.



Para finalizar, bloqueamos el login en la cuenta "windows", para que nadie trastee con ella y solo esté accesible a través de sudo:
# passwd -l windows
Y con esto ya tenemos hecha la tarea. A modo de recapitulación las ventajas son:
  • Realizamos una sola instalación y configuración por máquina, ahorrando espacio y trabajo.
  • Si la aplicación se estropea o deja de funcionar (en aplicaciones wine no es infrecuente, ya que el usuario tiene acceso total a la carpeta Archivos de Programa) no tenemos nada más que hacer una copia previa del directorio .wine con tar.gz y descomprimirla para dejar todo otra vez funcionando para todos los usuarios.
Y los inconvenientes:
  • Todos los usuarios de un mismo PC comparten la misma aplicación y carpeta de datos en /wine.
  • La aplicación va vinculada a la máquina y no al usuario. Si se mueve a otro PC no tiene acceso a sus datos o incluso puede no tener acceso a la aplicación
Por tanto, corresponde a cada cual valorar si merece o no la pena hacerlo así o de la forma tradicional.

Vamos que nos vamos.



lunes, 15 de enero de 2018

Poner las aplicaciones de Manjaro en español después una instalación fresca.

Después de instalar nuestro Manjaro XFCE en el primer arranque nos pide que instalemos los paquetes de idioma. Con las ansias de empezar a enredar lo dejamos para mas tarde y cerramos la ventana...de tal forma que luego no lo vuelve a pedir más veces y nos encontramos con que Firefox, Libreoffice y otras cosas están en inglis.

¿Cómo instalamos los paquetes de idiomas perdidos? Podemos ir al Gestor de Paquetes y buscarlos uno a uno, pero Manjaro nos tiene un sistema mejor para hacerlo de forma centralizada y ordenada.

Nos vamos al Gestor de Configuración de Manjaro en el menú:


Ahí elegimos "Configuración de idioma":


En esta ventana podemos ver los paquetes de idiomas instalados y los disponibles:


Con el botón de "Instalar paquetes" podemos elegir nuevos paquetes para añadir a las distintas aplicaciones:


Y ya está. Sencillo e indoloro, como todo en Manjaro.

domingo, 14 de enero de 2018

Como meter un recovery en Android desde linea de comandos.


Un dispositivo android tiene varios modos de arranque, desde un modo "mayormente muerto" (como el Pirata Roberts de La princesa prometida) hasta el modo completamente funcional.


Un modo muy usado si queremos trastear con el móvil es el "modo recovery", pero para sacarle toda su potencialidad normalmente nos vemos obligados a sustituir el recovery que trae por defecto el terminal por otro con más opciones. Aquí describiremos como meter un recovery nuevo mas potente a un dispositivo android.

Antes de entrar en faena y a modo de repaso para que no se me olvide, voy a enumerar los modos de los cuales tenemos noticia:

1. Modo normal/system.

Es el modo usual, con el dispositivo arrancado y funcional. Podemos interactuar con el mediante la pantalla táctil o mediante adb, conectándolo a un PC con el cable USB y enviando comandos hacia él.

El adb es además la vía mas sencilla y universal para reiniciar el móvil en los otros modos.

2. Modo recovery.:

En este modo el dispositivo arranca en un entorno restringido, que permite hacer varias tareas de mantenimiento que nos facilitan enredar con el dispositivo. Aquí el móvil se maneja con la pantalla táctil y/o los botones laterales y no es funcional en el sentido usual, ya que no se llega a cargar el sistema android.

Muchos móviles traen un stock recovery por defecto muy limitado, pero afortunadamente la comunidad ha creado recoverys sustitutos bastante avanzados, como CWM o TWRP.

Stock recovery, como vemos bastante insulso:


Recovery CWM, aquí hay mas opciones:


Recovery TWRP, con un GUI bonito y encima táctil:


Algunas de las funcionalidades que traen estos recoverys vitaminados son:

  • Cargar nuevas ROMs.
  • Hacer un reset de las distintas particiones y datos.
  • Instalar aplicaciones especiales, tipo SuperSU (para rootear) o Xposed (para añadir funcionalidades variadas).
  • Formateo, borrado, creación y montaje de particiones de la memoria SD interna del móvil.

Aquí y acá viene mejor explicado.

Para arrancar el móvil en recoverý suele haber una combinación especial de teclas de encendido o bien usando adb, como podemos ver aquí.

3. Modo fastboot/bootloader.

En este modo el móvil no puede ser manejado por su pantalla o botones, pero si podemos interactuar con él usando un cable USB y la utilidad fastboot.

Muchas veces tenemos un móvil brickeado (se queda congelando arrancando) o en bootloop (reinicia continuamente sin cargar el sistema). En estos casos si conseguimos ponerlo en modo fastboot tendremos una vía para restaurar o arreglar el sistema.

Normalmente se entra desde adb con el comando "adb reboot bootloader", aunque algunos dispositivos tienen combinaciones de teclas para arrancar en este modo. Es algo que tendremos que investigar en cada caso concreto.

Desde este modo se puede desbloquear el bootloader (en algunos móviles viene bloqueado para impedir instalar otras ROMs o recoverys) y trabajar con las particiones: borrar, formatear, sobreescribir imágenes nuevas. Es el modo que vamos a usar para meter un recovery más adelante.

4. Más abajo: modos cercanos al Amenti.

Aquí llegamos a terreno envuelto en brumas. Cada fabricante puede tener modos más profundos para arrancar el móvil, según estas normas básicas:
  • La nomenclatura depende del fabricante: download mode (aunque en algunos fabricantes es equivalente al fastboot), emergency mode, QDL mode, y seguro que hay muchos más.
  • En cada caso se usa herramientas especializadas, como Odin, SPFlashTool, MTKDroidTools, KDZ Firmware Update, MiFlash,...
  • Desde estos modos normalmente sólo se consigue flashear el móvil cargando una Stock ROM (ROM Oficial)
Cuando uno llega aquí es que tiene el móvil tan brickeado que no podemos conectar con él mediante fastboot y ya estamos en modo pánico. Mis tribulaciones con los malditos Xiami Redmi 1S son una prueba de ello.


Vamos al lío.

Yo he venido aquí a hablar de mi recovery, así que vamos a ello. Mi problema es que cada vez que tengo que meter un recovery me lanzo una y otra vez por el camino mas pedregoso: bajarme los drivers USB el teléfono, instalar una utilidad de flasheo, conseguir el fichero con el recovery para mi modelo de móvil (no vale cualquiera, hay que buscar el correcto en htcmania/xda-developers o generarlo nosotros) y realizar el flasheo de la partición que lo aloja.

Esa es la teoría. En la práctica, como la mayoría de estas utilidades solo funcionan bien en Windows no queda otra que arrancar dicho sistema, sortear los problemas con los drivers no firmados (la mayoría de los drivers de móviles están sin firmar), ver si detecta o no el dispositivo USB, ver si hay comunicación estable... y un sinfín de contratiempos más. Después de un par de horas infructuosas recuerdo que hay un método mucho más sencillo usando la línea de comandos de linux:

  1. Localizar y descargar el recovery. Suele ser un fichero .img que contiene dentro imagen de una partición con un mini-sistema Linux
  2. Conectar por adb y arrancar en modo fastboot.
  3. Desbloquear el bootloader, cargar el recovery y reiniciar.

Veamos la secuencia de comandos. Antes de nada debemos instalar las android-tools-adb y android-tools-fastboot en nuestro Linux, a veces vienen por separado o a veces en un único paquete android-tools. No hace falta ningún driver. También hay que habilitar el modo depuración USB en el menú de desarrollo del móvil.

Conectamos el móvil al PC por usb y tecleamos:
# adb devices
Si todo va bien saldrán numeritos y el nombre del teléfono. Ojo: quizá el móvil nos pregunte ahora o más adelante en su pantalla si damos permisos para aceptar la conexión desde el PC.

Reiniciamos el móvil en modo fastboot:
# adb reboot bootloader
En ese modo la pantalla no muestra nada interesante, la única manera de interactuar es a través del comando fastboot en el PC. Vemos si hay comunicación con dicho modo desde el ordenador tecleando:
# fastboot devices
Antes de nada, puede que el terminal tenga el bootloader bloqueado. Eso quiere decir que viene de fábrica configurado para impedir cambiar el recovery y/u otras partes del sistema. En ese caso lo que haremos será desloquearlo con uno de estos 2 comandos:
# fastboot oem unlock
o
# fastboot oem unlock-go
Podemos ver el estado del bootloader con:
# fastboot oem device-info
y/o
# fastboot getvar all
Debe aparecer algo así como: "Device Unlocked: true".

Una vez confirmamos que el móvil está desbloqueado, procedemos a sustituir el revovery por uno nuevo descargado de Internet (recordemos: el recovery debe ser compatible con nuestro terminal, no se pueden hacer mezclas a riesgo de brickear el movil).
# fastboot flash recovery twrp.img
También es posible hacer una prueba del recovery en dique seco, sin reescribir el original. Así confirmamos su buen funcionamiento/compatibilidad o bien lo ejecutamos para algo puntual sin sustituir el recovery que hay instalado:
# fastboot boot twrp.img
Una vez sobreescrito el nuevo recovery, reiniciamos:
# fastboot reboot
El móvil debe reiniciar bien y una vez arrancado, desde el adb podemos reiniciar en el recovery para operar con él:
# adb devices
# adb reboot recovery
Y ya está, espero que la próxima vez no tenga que perder el tiempo con Windows cuando quiera hacer esto.