Archivo de la categoría: Linux

Servidor central de películas para una o más tablets con la raspberry pi zero mediante wifi

La siguiente situación es conocida por muchos: vamos a hacer un viaje largo en coche que dura horas, pero los niños no aguantan y al poco rato de haber comenzado ya empiezan a preguntar cuanto queda o si hemos llegado ya. Para hacerles más ameno el viaje se les ponen películas para que vayan entretenidos una buena parte del viaje.

El objetivo de este artículo es reutilizar las tablets android e ipad (también funciona con los móviles) que tenemos por casa para que reproduzcan los vídeos que hay almacenados en una raspberry pi zero mediante wifi. Así los niños estarán entretenidos en el coche, en un restaurante, en la sala de espera espera del médico, etc., además cada uno podrá ver una película distinta y no tendremos que realizar ninguna inversión grande para lograrlo más allá de una tarjeta SD y una raspberry pi zero w.

Lo primero es descargarse la última versión del sistema operativo Raspbian Lite desde la web oficial.

Después hay que grabarla en una tarjeta SD (recomiendo una con class 10). Aquí se explica cómo hacerlo desde varios sistemas operativos.

Esta creará dos particiones. En la que es FAT32 y está etiquetada como boot hay que:

  • Crear un fichero vacío llamado ssh o ssh.txt para habilitar la conexión ssh a la raspberry pi.
  • Crear otro fichero llamado wpa_supplicant.conf e introducir en este lo siguiente (cambiando los valores ssid y psk por los de la red wifi correspondiente):

Ahora hay que introducir la tarjeta SD en la raspberry pi y alimentarla mediante un cargador usb de al menos 500mA.

Si todo va bien se podrá conectar a la raspberry mediante ssh a la IP que le ha dado el router.

Para asegurarse que instalaremos las últimas versiones del software hay que hacer una actualización de los repositorios:

Instalar hostapd (para que la raspberry haga de punto de acceso), dnsmasq (para que pueda dar direcciones IP), samba (para compartir ficheros) y lighttpd (para poder apagar la raspberry desde el navegador):

Para que los dispositivos se conecten a una red wifi creada por las raspberry hay que configurar el hostpad, para ello crear con el usuario root el fichero /etc/hostapd/hostapd.conf con el siguiente contenido (cambiando los valores ssid y wpa_passphrase por los de la red wifi que vamos a crear y el valor channel por el *canal de la red wifi del router):

*Cuando estamos en casa, para que funcionen correctamente en la raspberry tanto la red wifi creada como la red wifi que hemos configurado al principio para conectarse, hay que configurar el mismo canal wifi porque la raspberry no permite trabajar con varios canales a la vez.

Editar con el usuario root el fichero /etc/default/hostapd y añadir el siguiente contenido:

Después, cada vez que arranque la raspberry hay que ejecutar un script para activar correctamente la red wifi creada, para ello crear con el usuario root el fichero /usr/local/bin/hostapdstart con el siguiente contenido:

y editar con el usuario root el fichero /etc/rc.local y poner antes de la linea que tiene exit 0 el siguiente contenido:

A continuación hay que configurar el dnsmasq para que de IPs a los dispositivos que se conecten a la raspberry en la subred 192.168.50.0/24, para ello editar con el usuario root el fichero /etc/dnsmasq.conf y añadir al final del fichero el siguiente contenido:

Después hay que configurar la raspberry para que se conecte a nuestro router (otra vez como al principio), para ello editar con el usuario root el fichero /etc/network/interfaces y añadir al final el siguiente contenido:

Para compartir los ficheros se tiene que configurar samba. Primero ejecutar:

Después añadir con el usuario root al final del fichero /etc/samba/smb.conf el siguiente contenido:

En la carpeta /home/pi/share es donde se deben almacenar los vídeos que luego se quieran reproducir. Puedes enchufar un disco usb a la rasberry para copiar los vídeos; descargarlos de una NAS, de una página web, etc.; instalar un cliente de torrent o lo que se te ocurra.

Para apagar la raspberry fácilmente desde el navegador, hay que dar permisos de sudo a lighttpd, por tanto ejecutar:

Y añadir al final el siguiente contenido:

Después activar el módulo cgi para lighttpd:

Sustituir con el usuaro root el fichero /etc/lighttpd/conf-enabled/10-cgi.conf con el siguiente contenido:

Crear con el usuario root el fichero /var/www/html/index.html con el siguiente contenido:

Crear con el usuario root el fichero /var/www/html/apaga.sh con el siguiente contenido:

Como último paso en la raspberry, ejecutar:

Para que no haga falta esperar conexión a la red, seleccionar 3-Boot Options/B2 Wait for Network at Boot/NO y para tener la máxima memoria posible 7 Advanced Options/A3 Memory Split, poner 16 y pulsar OK. Seleccionar Finish y decir si a reiniciar la raspberry.

Finalmente instalar la aplicación VLC de videolan en los dispositivos, después configurarlos para que se conecten a la red wifi de la raspberry, arrancar el VLC, seleccionar la opción Red local, elegir RASPBERRYPI, escoger la carpeta Peliculas y pulsar sobre la película que se quiera reproducir.

En el coche, la rasberry se puede alimentar con un cargador de mechero a USB, en otro lugares se puede alimentar mediante una powerbank.

Para apagar la raspberry, sólo hay que abrir un navegador en uno de los dispositivos y acceder a la dirección http://192.168.50.1

Por último agradecer a este mensaje en los foros de la raspberry donde se explica cómo hacer funcionar como punto de acceso a la vez que cliente.

Espero que os sea tan útil como a mi para amenizar la espera a los niños o incluso utilizarlo tu sólo cuando vas en transporte público o estás en un hotel.

Crear un demonio en el linux embebido en placas

Ahora que están de moda las placas que contienen un linux embebido como las beagleboard, las raspberry pilas foneras, he creido interesante escribir un artículo en el cual se explica cómo ejecutar una tarea por tiempo indefinido desde que arranca la placa  y sin necesidad de acceder por shell a la misma.

Presupongo que tienes el compilador cruzado que genera ejecutables para la plataforma de la placa y que tienes acceso a ella mediante shell con el usuario root.

Nuestro objetivo es sencillo, crear lo que se denomina en entornos linux y unix un demonio (en windows es un servicio) lo más sencillo posible. Un demonio no es nada más que una aplicación que se ejecuta en segundo plano y no muestra directamente datos al usuario ni este puede interactuar con ella.

Como queremos que el ejemplo sea bastante sencillo nuestro demonio simplemente va a escribir en un fichero una cadena cada cierto tiempo. Vosotros podreis modificarlo para que haga lo que querais (leer y escribir datos en un puerto serie, analizar imágenes de una webcam, manejar GPIO, crear un servicio para internet, etc).

Scripts de demonios:

Normalmente cuando se arranca un sistema linux, después de cargar el kernel se ejecuta el proceso init, que es el proceso padre del que dependerán el resto de procesos que se ejecuten en el sistema. Este proceso lee el fichero /etc/inittab para saber entre otras cosas en qué nivel de arranque (runlevel de 1 a 5) debe iniciar el sistema.

Dependiendo de ese nivel de arranque se ejecutarán unos scripts ubicados en la carpeta correspondiente. Así por ejemplo si el nivel es 3, los scripts de la carpeta /etc/rc3.d que empiecen por S (Start) se ejecutarían al arrancar. Estos scripts tienen un número que indica en qué orden se ejecutan (se puede repetir el número).

Pero… un momento… ¡¡¡ Si estos ficheros son en realidad son enlaces simbólicos !!!.

Efectivamente, en realidad son accesos directos que apuntan al directorio /etc/init.d donde realmente están los scripts para los demonios. El proceso init lee de la carpeta /etc/rc3.d los enlaces que empiezan por S y ejecuta el script al que apunta con el parámetro start. Igualmente cuando se apaga o se reinicia el sistema el proceso init lee de la carpeta /etc/rc0.d o /etc/rc6.d  respectivamente los enlaces que empiezan por K y ejecuta el script al que apunta con el parámetro stop.

Los scripts que se encuentran en la carpeta /etc/init.d son en realidad scripts shell que dependiendo del parámetro que se le pase (start, stop, reload, etc) ejecuta el comando necesario para lo que se requiere. Ni que decir tiene que igualmente nosotros podemos ejecutar por nuestra cuenta el script con los parámetros mencionados para parar o arrancar el demonio desde una consola.

Por tanto vamos a crear un sencillo script que arranque o pare nuestro demonio. Lo crearemos dentro del directorio /etc/init.d y lo llamaremos nohacenada con el siguiente contenido:

Este ejemplo muestra un sencillo script donde se espera como parámetro una cadena start o stop. Si es start simplemente arranca la aplicación. Si es stop comprueba si existe el fichero /var/run/nohacenada.pid para saber si la aplicación está corriendo, después lee su contenido, que es el identificador del proceso, para posteriormente mandarle una señal kill y que este pueda cerrarse por si sóla limpiamente. Si no es ninguno de los dos parámetros anteriores es que el usuario intentó ejecutar el script por su cuenta sin poner start o stop como parámetro.

El script debe tener permisos 755  y pertenecer a root por lo que debemos dárselo de esta forma desde una consola shell con el usuario root:

Además hay que crear los enlaces simbólicos en el directorio correspondiente para que init sepa que tiene que arrancarlo (niveles 2, 3, 4 y 5) y pararlo (niveles 0, 1 y 6):

o si te lo permite el linux que tienes instalado, simplemente:

Con estos pasos ya hemos terminado nuestro script para que el proceso init pueda arrancar o parar nuestro demonio.

El demonio:

Para crear nuestro demonio usaremos el lenguaje C, que es el lenguaje estandar de linux. Nuestra aplicación se convertirá en demonio para quedar residente en el sistema permanentemente hasta que se termine mediante kill.

Programaremos nuestra aplicación para que informe de los errores en el log, genere un fichero pid, cree un hilo de ejecución que se convierta en demonio y escriba una cadena cada segundo mientras espera a que se termine la aplicación mediante una señal.

Dado que la aplicación no muestra datos al usuario este no sabe que está pasando por dentro, por eso habrá que informarle a través de los log. De esto se encargan las funciones openlog y syslog. Toda la información podrá ser consultada en el fichero /var/log/syslog.

Muchos demonios generan en el directorio /var/run un fichero con el nombre de la aplicación y extensión pid. Dentro guardan el PID o identificador de proceso en formato numérico. Con esto se obtienen dos ventajas: por un lado la misma aplicación sabe si ya hay una copia de ella misma ejecutandose para no duplicar procesos; por otro lado como guarda el pid dentro del fichero cualquier proceso puede leerlo para poder comunicarse con la aplicación (por ejemplo el comando kill que explicaré más adelante).

Para crear un demonio la aplicación principal crea un hilo de ejecución con fork y la aplicación principal se saldrá. Esto provoca que el hilo de ejecución se quede huerfano. Después se ejecuta umask para no heredar los permisos de los ficheros del proceso padre. A continuación se ejecuta setsid para que el proceso huerfano tenga su propio SID y sea un proceso independiente para el sistema operativo.  Por otro lado cambiaremos de directorio de ejecución para apuntar a la raiz con un chdir ya que es el único directorio seguro que existe en linux.  Finalmente cerraremos con un close la entrada estandar, la salida estandar y la salida de errores ya que no las necesitamos.

Con la función signal haremos que cuando el usuario (o init) nos envíe un comando kill (sin el -9) salgamos de la aplicación limpiamente. Esto es debido a que cuando se ejecuta kill <pid> lo que se está haciendo realmente es enviar una señal SIGTERM a la aplicación. La aplicación recupera la señal y ejecuta la función asociada mediante la función signal. En el ejemplo de más abajo veremos que se asocia a la función adios que simplemente cambia una variable para que se salga del bucle principal. Mientra se espera a recibir la señal, cada segundo se está escribiendo en el fichero /tmp/nohacenada.txt una cadena.

Al salir del bucle se escribirá en el fichero anterior otra cadena y cerramos ese fichero. Igualmente cerraremos el log y se borrará el fichero pid para que se pueda volver a ejecutar la aplicación nuevamente (en un arranque del sistema o nosotros mismos).

Dejo el código fuente de la aplicación llamado nohacenada.c para que os hagais una idea y poder hacer vuestros demonios basados en este:

Para compilarlo depende del toolchain para cada plataforma, pero sería algo parecido a esto:

Como seguramente hayais instalado un compilador cruzado en vuestro ordenador de sobremesa, habrá que subir el fichero ejecutable a la placa. Yo recomiendo que useis scp en linux o winscp en windows si la placa tiene acceso a la red ethernet o wifi ya que hace uso del demonio sshd (el que se usa para las sesiones de consola remotas por ssh).

Una vez subido el fichero a la placa debemos darle permisos de ejecución, asignarle como propietario al usuario root y moverlo a la ruta /usr/sbin a través de la consola shell con el usuario root de la siguiente manera:

Ahora podeis probar si funciona realmente simplemente ejecutando:

Podeis comprobar en la carpeta /tmp si hay un fichero llamado nohacenada.txt y consultarlo, también podeis mirar en la carpeta /var/run si existe un fichero llamado nohacenada.pid y visualizarlo. Si no veis nada podeis mirar el fichero /var/log/syslog para ver si hubiese algún error de la aplicación nohacenada.

Y para pararlo:

Con esto espero que le saqueis bastante provecho a vuestras placas con linux embebido ya que así conseguis que nada más encenderla se ejecute el programa sin tener que hacer vosotros nada por vuestra cuenta. Quizá en el futuro explique cómo programar módulos para el kernel y extender la funcionalidad de vuestra placa aún más lejos (drivers para hardware, sistemas de ficheros, llamadas al sistema, etc).