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

domingo, 12 de marzo de 2017

Otra pedrada a la obsolescencia programada: cambiando la batería de un ebook.

Me ha llegado un ebook "averiado" para tirar a reciclaje o para hacer lo que quisiese con él. El dispositivo en cuestión es este:



Y el síntoma es que no se encendía, estaba como muerto. Tras consultar en Internet veo que lo mas seguro es que la batería se haya estropeado y como no tengo nada que perder, me decido a abrirlo para verle las tripas.

Una vez abierto observo que la batería que tiene es una batería de polímeros de litio (es blanda, como de arcilla, y tiene una pequeña circuitería de carga en un lateral, donde entran los cables) de 3.7V, como las baterías de cualquier móvil. Luce como esta sacada al azar de Aliexpress:



Está pegada con un adhesivo a la placa base y unida a ésta por los dos típicos cables rojo(+) y negro(-). Corto los cables que entran en la batería y la saco de la placa. Tengo varias baterías de móviles viejo dando vueltas por ahí en un cajón...¿cargo una y la pongo a ver si da el pego?. Vamos allá: la cargo en su propio móvil y luego la sueldo respetando la polaridad y la coloco donde estaba la original. Queda así:



Una panorámica de la placa con la batería vieja al lado:



Hecho esto, doy al botón de encendido y ¡voilá!:



El ebook funciona, simplemente estaba muerta su batería. Si pruebo a conectar el conector USB que tiene a un cargador de móvil verifico que empieza a cargarse. No me fío mucho de que la circuitería de la batería del móvil (que ya tiene mas de 10 años y estaba bastante fastidiada) no vaya a permitir cargar bien. Pero bueno, ya sé que por 6 euros puedo comprar una batería específica para ebooks en Aliexpress y soldarla. Otro aparato recuperado y tomo nota para cuando me dejen de ir los 2 ebooks que tengo en casa, un Kindle y un venerable Sony PRS-505.

Ahora mi editorial: es vergonzoso que los lectores de libros electrónicos usen este tipo de baterías díficiles de reemplazar cuando llegan al final de su vida útil. ¿Tan difícil es poner un compartimento con baterías intercambiables como las de un móvil o una cámara?.

La causa es sencilla: un ebook es un aparato que, a diferencia de la mayoria de chismes tecnológicos que nos ofrece el capitalismo terminal, nunca va a quedar obsoleto en funcionalidad o va a ir tan lento que haya que comprar otro para ponerse al día. A fin de cuentas se basa en un sistema que ha funcionado desde las tabillas de arcilla de Ur: marcas permanentes sobre una superficie.

Por tanto la solución pasa por entorpecer al máximo su durabilidad, como ya vimos en este blog con los lápices de la pizarra Interwrite, y yo por mi cuenta veo yo cuando desmonto un cepillo de dientes eléctrico "averiado" y compruebo que tiene una batería patatera de NiMh (a estas alturas del baile andan con baterías de NiMh, carajo, si al menos fueran de NiFe) soldada al motor y enclaustrada, de tal manera que es bastante complicado cambiarla sin romper nada. En el caso de los ebooks esto empieza por poner una batería soldada a la placa difícil de reemplazar para un comprador habitual.

Al final un ebook bien cuidado y con baterías intercambiables fácilmente pordía durar decenios. Si le añades un cargador USB solar además te haces independiente de las eléctricas y sus secuaces del gobierno. Todo esto suena muy subversivo, que mundo mas raro.

jueves, 9 de marzo de 2017

La suma hash difiere, 406 not acceptable o index failed to download al hacer "apt-get update"

Finalmente lo tengo que apuntar aquí porque cada vez que me pasa me tiro un rato hasta que me acuerdo la solución. Al hacer apt-get update o pkgsync en algunos equipos aparece este enigmático mensaje:
W: Imposible obtener http://blablabla/archive/ubuntu/dists/trusty-backports/main/binary-amd64/Packages  La suma hash difiere
W: Imposible obtener http://blablabla/archive/archive/ubuntu/dists/trusty-backports/main/binary-i386/Packages  La suma hash difiere
O
100% [Trabajando]W: Se produjo un fallo al descargar http://blablaba/desarrollo/pizarras/wheezy/dists/wheezy/linex/binary-amd64/Packages: 406  Not Acceptable
W: Se produjo un fallo al descargar http://blablaba/desarrollo/pizarras/wheezy/dists/wheezy/linex/binary-i386/Packages: 406  Not Acceptable
E: Some index files failed to download. They have been ignored, or old ones used instead.
E: No se pudo reconstruir el almacén de paquetes
Evidentemente esto impide la instalación o actualización de paquetes, ya que hay algo corrupto en el sistema local de paquetes que le impide seguir. La solución nos la dió nuestro compañero Paco hace ya meses y paso a reflejarla aquí:
# cd /var/lib/apt/lists
# rm -rf *
Con esto se borra todo el contenido, incluyendo el subdirectorio "partial". Con esto queda limpio de polvo y paja y ya se puede actualizar todo bien.

martes, 7 de marzo de 2017

2x1: multiseat en las aulas (Parte III)

Bueno, tenía que llegar tarde o temprano al tema del sonido en multiseat. Tras montar el multiseat aquí y aquí hace varios días me pidieron hacer funcionar el sonido de forma autónoma en cada seat.

1. Configuracion del seat.

En la entrada anterior le dediqué un apartado al tema y concluí que si usamos homes montados sobre NFS había que poner 2 tarjetas de sonido físicas, ya que pulseaudio no funcionaba bien por separado en cada seat compartiendo una única tarjeta. Así que he pinchado una tarjeta PCI de sonido normalita sacada de algún desguace de PC de los 90. El lspci me muestra esa tarjeta de audio adicional:
# lspci | grep -i audio
00:1b.0 Audio device: Intel Corporation 82801JI (ICH10 Family) HD Audio Controller
06:00.0 Multimedia audio controller: Ensoniq ES1370 [AudioPCI]
Como siempre, por defecto ambas tarjetas están vinculadas al seat0, veámoslo:
# loginctl seat-status seat0 | grep sound

          ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0
          │ sound:card0 "Intel"
          │ ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input10
          │ ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input11
          │ ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input12
          │ ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input13
          │ ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input14
          │ ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input15
          │ ├─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input16
          │ └─/sys/devices/pci0000:00/0000:00:1b.0/sound/card0/input17
          ├─/sys/devices/pci0000:00/0000:00:1e.0/0000:06:00.0/sound/card2
          │ sound:card2 "AudioPCI"
          ................
          ................
Ahora vinculamos la tarjeta nueva, como ya vimos en las anteriores entradas, al seat-1:
# loginctl attach seat-1 "/sys/devices/pci0000:00/0000:00:1e.0/0000:06:00.0/sound/card2"
¿Estará ya en seat-1?. Como dicen en las Vegas Altas, vela ahíla:
# loginctl seat-status seat-1
seat-1
        Sessions: *c2
         Devices:
                  ├─/sys/devices/pci0000:00/0000:00:06.0/0000:02:00.0/drm/card0
                  │ drm:card0
                  ├─/sys/devices/pci0000:00/0000:00:06.0/0000:02:00.0/drm/renderD128
                  │ drm:renderD128
                  ├─/sys/devices/pci0000:00/0000:00:06.0/0000:02:00.0/graphics/fb0
                  │ [MASTER] graphics:fb0 "nouveaufb"
                  ├─/sys/devices/pci0000:00/0000:00:1d.7/usb2/2-2
                  │ usb:2-2
                  │ ├─/sys/devices/pci0000:00/0000:00:1d.7/usb2/2-2/2-2.1/2-2.1:1.0/0003:046D:C050.0001/input/input5
                  │ │ input:input5 "Logitech USB-PS/2 Optical Mouse"
                  │ └─/sys/devices/pci0000:00/0000:00:1d.7/usb2/2-2/2-2.2/2-2.2:1.0/0003:046D:C312.0002/input/input6
                  │   input:input6 "LITEON Technology USB Multimedia Keyboard"
                  └─/sys/devices/pci0000:00/0000:00:1e.0/0000:06:00.0/sound/card2
                    sound:card2 "AudioPCI"
Al reiniciar e iniciar sesión, podemos ver con un "ps aux" que pulseaudio se ejecuta en 3 instancias: una para lightdm y otra para cada una de las 2 sesiones en sendos seat.

El chasco viene cuando descubrimos que ambos seat reproducen el sonido por la tarjeta de audio Intel, ignorando la Ensoniq... ¿qué pasa aquí?. Si miramos la configuración de audio con pavucontrol en cualquiera de los seat vemos:
Horror de horrores: ambos seat ven las dos tarjetas de audio. Esto no es lo que me habían contado. Cada pulseaudio debería ver solo la tarjeta asociada a su seat, como sucede con los teclados, ratones y VGA. Esto tiene toda la pinta de ser un bug de pulseaudio que no maneja bien el tag ID_SEAT definido en su rules.d, pero no sé como arreglarlo en ese nivel.

2. El truco para activar una u otra tarjeta de sonido según el seat.

Lo que si me doy cuenta en la imagen anterior es que yo puedo, en cada combo, seleccionar el perfil "Desactivado" en una u otra tarjeta y conseguir que el sonido salga por la Intel o la Ensoniq, ignorando la otra. Eso es una rendija por la que colarse: si puedo hacerlo a mano...¿podria hacerlo al iniciar sesión en función del seat?. Dicho de otra manera...¿puedo controlar pulseaudio con comandos?. Pues si, encuentro en esta entrada que existe el comando "pacmd" que permite controlar todos y cada uno de los parámetros de una instancia de pulseaudio, incluyendo hacer copias de seguridad y restaurarlas. Con:
 ~$ pacmd help
Available commands:
    help                      Show this help
    list-modules              List loaded modules
    list-cards                List cards
    list-sinks                List loaded sinks
    list-sources              List loaded sources
    list-clients              List loaded clients
    list-sink-inputs          List sink inputs
    list-source-outputs       List source outputs
    ......
    play-file                 Play a sound file (args: filename, sink|index)
    dump                      Dump daemon configuration
    dump-volumes              Debug: Show the state of all volumes
    shared                    Debug: Show shared properties
    exit                      Terminate the daemon
Vemos todos los posibles comandos para obtener o fijar los parámetros de configuración. Con "pacmd dump > config.txt" haríamos una copia de seguridad, que podríamos restaurar con "pacmd < config.txt". Profundicemos: realmente la configuración de pulseaudio se guarda en:
 ~$ ls -1 ~/.config/pulse
cookie
e8418e23c6b647548fea260c81d4742b-card-database.tdb
e8418e23c6b647548fea260c81d4742b-default-sink
e8418e23c6b647548fea260c81d4742b-default-source
e8418e23c6b647548fea260c81d4742b-device-volumes.tdb
e8418e23c6b647548fea260c81d4742b-stream-volumes.tdb
Siendo los .tdb un tipo de BBDD bastante simple basado en pares "clave/datos binarios" usados principalmente en Samba. Son bastante crípticos incluso con la herramienta tdbtool, ya que guardan la información en formato binario, así que los ignoraremos y usaremos pacmd que es menos huraño.

Una curiosidad es el prefijo "e8418e23c6b647548fea260c81d4742b" de cada fichero. Es un UUID que sospecho que va asociado a la máquina, aunque no he podido averiguar de donde sale, y que permite tener configuraciones separadas de pulseaudio en función de la máquina en la que inicia sesión el usario, lo cual es muy útil cuando nuestros usuarios tienen un home centralizado en un servidor NFS.

Bueno, vamos al lío: tenemos que activar una u otra tarjeta al iniciar sesión en función del seat. Esto lo enfocaré como un parche temporal ya que según dice la parte contratante de la primera parte cada instancia de pulseaudio debería asociarse a la tarjeta de sonido vinculada seat correspondiente y santaspascuas. Hasta que esto sea cierto usaremos estos scripts para hacer funcionar el sistema:
# cat /usr/bin/multiseat-sound
#!/bin/bash
if [ "$XDG_SEAT" = "seat0" ]
then
   pacmd set-card-profile 0 output:analog-stereo+input:analog-stereo
   pacmd set-card-profile 1 off
else
   pacmd set-card-profile 0 off
   pacmd set-card-profile 1 output:analog-stereo+input:analog-stereo
fi
Sencillo: si estamos en seat0 la tarjeta 0 se activa y la 1 se desactiva. Si es seat-1 se realiza la acción opuesta. Los valores output:analog-stereo+input:analog-stereo y off los he obtenido cambiando en pavucontrol a golpe de ratón y luego husmeando con "pacmd dump". Como queremos que esto se ejecute en cada inicio de sesión, metemos un .desktop en xdg/autostart:
# cat /etc/xdg/autostart/multiseat-sound.desktop
[Desktop Entry]
Type=Application
Name=Multiseat-Sound
Comment=Configura sonido por multiseat
Exec=/usr/bin/multiseat-sound
Terminal=false


3. Limpiando la casa.

Por último, si queremos quedar todo en recogido y en orden al salir de sesión debemos configurar un script de salida en lightdm:
 # cat /etc/lightdm/lightdm.conf.d/14-logout.conf
[SeatDefaults]
session-cleanup-script=/usr/bin/multiseat-sound-off
Siendo
# cat /usr/bin/multiseat-sound-off
#!/bin/bash
pacmd set-card-profile 0 output:analog-stereo+input:analog-stereo
pacmd set-card-profile 1 output:analog-stereo+input:analog-stereo
Y con esto ya podemos tocar duetos con nuestros multiseat. Hasta podemos lanzar un duelo de guitarras haciendo salir por una a Joe Satriani y por otra a Yngwie Malmsteen y así alcanzamos el Nirvana en dobleplusestéreo.



jueves, 2 de marzo de 2017

Configuración de OpenWrt como routed client

Cuando tenemos nuestro router con OpenWrt y lo queremos usar como dispositivo wifi (suponiendo que el chipset esté soportado por OpenWrt, ĺo cual no siempre sucede) hay tres escenarios posibles:

  • Usarlo como repetidor para extender una wifi preexistente, creando una red wifi con un ESSID nuevo que amplía el alcance de la anterior.
  • Usarlo para crear un punto de acceso con una red wifi nueva, a partir de una conexión que ya nos trae acceso a internet cableada por ethernet. Lo que los chicos de OpenWrt llaman "Dumb AP".
  • Usarlo para conectar como cliente a una red wifi preexistente y luego permitir conexión de dispositivos adicionales usando los puertos ethernet del router, enrutando el tráfico entre ambas tarjetas de red (wifi y ethernet) usando NAT. (Nota: hay otras soluciones aparte de NAT, como usar rutas estáticas, pero no los aplicaremos aquí).

Bueno, pues esta última es la opción que he tenido que configurar en los recientes días para acceder a la red wifi y conectar la Raspberry Pi a ella mediante un cable ethernet (es una Pi sin wifi y los pinchos USB que probé no tenían unos drivers muy estables y/o eficientes). El esquema (cogido de la web de OpenWrt) sería:


Las IP Azules son de la red preexistente y las rojas de la red nueva que creamos. Veamos como configurar los distintos ficheros para llegar hasta aquí.

El router usado ha sido, una vez más, un indestructible Astoria gris de ya.com, el ARV4518PW modelo R01A. Esta vez he ido más allá y le he metido el ultimísimo firmware lede-lantiq-xway_legacy-ARV4518PWR01A-squashfs-sysupgrade.bin, del proyecto LEDE que es una escisión de OpenWrt. Como diría Joseph Stalin, los proyectos de SW libre están llenos de trotskistas.

Recordemos que el router tiene una memoria NAND de 4Mb de la cual solo se puede usar 3.6Mb (si pasamos de ahí se sobreescriben los datos de calibración de la wifi), así que cabe la imagen y poco más. Si queremos instalar paquetes adicionales deberíamos usar otro router o bien pinchar un pendrive USB y configurarlo para instalar aplicaciones allí. Si no es así no podermos añadir paquetes nuevos, aunque realmente para este caso que nos ocupa no hacen falta. El espacio en disco tras la instalación es:
# root@ASTORIA:/etc/config# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/root                 2304      2304         0 100% /rom
tmpfs                    30040        48     29992   0% /tmp
/dev/mtdblock5             320       264        56  83% /overlay
overlayfs:/overlay         320       264        56  83% /
tmpfs                      512         0       512   0% /dev
El banner de login es:
    /        /\      _    ___ ___  ___
   /  LE    /  \    | |  | __|   \| __|
  /    DE  /    \   | |__| _|| |) | _|
 /________/  LE  \  |____|___|___/|___|                      lede-project.org
 \        \   DE /
  \    LE  \    /  -----------------------------------------------------------
   \  DE    \  /    Reboot (SNAPSHOT, r3598-eb09d79)
    \________\/    -----------------------------------------------------------
La carga del sistema nuevo la he hecho desde el OpenWrt Barrier Breaker que tenia previamente, conectando por ssh, descargando el fichero .bin desde mi pc (192.168.0.100) a /tmp y luego ejecutando sysupgrade:
# cd /tmp
# wget http://192.168.0.100/lede-lantiq-xway_legacy-ARV4518PWR01A-squashfs-sysupgrade.bin
# sysupgrade -v lede-lantiq-xway_legacy-ARV4518PWR01A-squashfs-sysupgrade.bin
Una vez hecho el sysupgrade el router reinicia manteniendo la configuracion IP y de telnet/ssh que tenia antes. Por tanto para configurarlo conectamos por telnet o ssh y procedemos a editar los ficheros de configuración tal como describimos a partir de ahora.

Empezamos con la configuracion de tarjetas de red, la red ethernet con ip fija 192.168.1.1 en la red 192.168.1.X. La red wifi recibirá su IP por dhcp del otro router wifi al que nos conectemos (que suponemos en la red 192.168.0.X):
# cat /etc/config/network
config interface 'loopback'
    option ifname 'lo'
    option proto 'static'
    option ipaddr '127.0.0.1'
    option netmask '255.0.0.0'

config interface 'lan'
    option ifname 'eth0'
    option type 'bridge'
        option proto 'static'
    option ipaddr '192.168.1.1'
    option netmask '255.255.255.0'

config 'interface' 'wan'
        option 'proto'      'dhcp'
Aquí configuramos la tarjeta wifi como cliente de la red wifi remota (clave WPA2/PSK) :
# cat /etc/config/wireless
config wifi-device  radio0
    option type     mac80211
    option channel  11
    option macaddr    00:13:fe:e9:2a:5a
    option hwmode    11g

    # REMOVE THIS LINE TO ENABLE WIFI:
    option disabled 0

config wifi-iface
    option device 'radio0'
    option mode 'sta'
    option network 'wan'
    option ssid 'MI_WIFI'
    option encryption 'psk2'
    option key 'MI_PASSWORD'
 
Configuración del servidor DHCP para que reparta IP por la red ethernet (lan). Aunque es aconsejable poner IP fijas de forma manual en los dispositivos de esa red, para que tengan su dirección nada mas arrancar y agilizar la conexión:
# cat /etc/config/dhcp
config dnsmasq
    option domainneeded '1'
    option boguspriv '1'
    option filterwin2k '0'
    option localise_queries '1'
    option rebind_protection '1'
    option rebind_localhost '1'
    option local '/lan/'
    option domain 'lan'
    option expandhosts '1'
    option nonegcache '0'
    option authoritative '1'
    option readethers '1'
    option leasefile '/tmp/dhcp.leases'
    option resolvfile '/tmp/resolv.conf.auto'

config dhcp 'lan'
    option interface 'lan'
    option start '100'
    option limit '150'
    option leasetime '12h'
    option ignore '0'
    option dhcpv6 'server'
    option ra 'server'

config dhcp 'wan'
    option interface 'wan'
    option ignore '1'

config odhcpd 'odhcpd'
    option maindhcp '0'
    option leasefile '/tmp/hosts/odhcpd'
    option leasetrigger '/usr/sbin/odhcpd-update'

Configuramos el servicio ssh con dos instancias para que se permita el acceso remoto a router desde ambas redes. Por la wifi se entrará por el puerto 22 y por la ethernet por el puerto 443:
# cat /etc/config/dropbear
config dropbear
    option PasswordAuth 'on'
    option RootPasswordAuth 'on'
    option Port         '22'
    option Interface    'wan'

config dropbear
        option PasswordAuth 'on'
        option RootPasswordAuth 'on'
        option Port         '443'
        option Interface    'lan'
En el fichero firewall definimos el NAT entre lan (ethernet) y wan (wifi):
# cat /etc/config/firewall
config defaults
    option syn_flood    1
    option input        ACCEPT
    option output        ACCEPT
    option forward        REJECT
# Uncomment this line to disable ipv6 rules
#    option disable_ipv6    1

config zone
    option name        lan
    option network        'lan'
    option input        ACCEPT
    option output        ACCEPT
    option forward          REJECT       

config zone
    option name        wan
    option network        'wan'
    option input        ACCEPT
    option output        ACCEPT
    option forward        ACCEPT
    option masq        1
    option mtu_fix        1

config forwarding
    option src        lan
    option dest        wan

# We need to accept udp packets on port 68,
# see https://dev.openwrt.org/ticket/4108
config rule
    option name        Allow-DHCP-Renew
    option src        wan
    option proto        udp
    option dest_port    68
    option target        ACCEPT
    option family        ipv4

# Allow IPv4 ping
config rule
    option name        Allow-Ping
    option src        wan
    option proto        icmp
    option icmp_type    echo-request
    option family        ipv4
    option target        ACCEPT

# Allow DHCPv6 replies
# see https://dev.openwrt.org/ticket/10381
config rule
    option name        Allow-DHCPv6
    option src        wan
    option proto        udp
    option src_ip        fe80::/10
    option src_port        547
    option dest_ip        fe80::/10
    option dest_port    546
    option family        ipv6
    option target        ACCEPT

# Allow essential incoming IPv6 ICMP traffic
config rule
    option name        Allow-ICMPv6-Input
    option src        wan
    option proto    icmp
    list icmp_type        echo-request
    list icmp_type        echo-reply
    list icmp_type        destination-unreachable
    list icmp_type        packet-too-big
    list icmp_type        time-exceeded
    list icmp_type        bad-header
    list icmp_type        unknown-header-type
    list icmp_type        router-solicitation
    list icmp_type        neighbour-solicitation
    list icmp_type        router-advertisement
    list icmp_type        neighbour-advertisement
    option limit        1000/sec
    option family        ipv6
    option target        ACCEPT

# Allow essential forwarded IPv6 ICMP traffic
config rule
    option name        Allow-ICMPv6-Forward
    option src        wan
    option dest        *
    option proto        icmp
    list icmp_type        echo-request
    list icmp_type        echo-reply
    list icmp_type        destination-unreachable
    list icmp_type        packet-too-big
    list icmp_type        time-exceeded
    list icmp_type        bad-header
    list icmp_type        unknown-header-type
    option limit        1000/sec
    option family        ipv6
    option target        ACCEPT

# include a file with users custom iptables rules
config include
    option path /etc/firewall.user

Y ya está, con esto conectamos remotamente a la wifi, enchufamos la Raspberry Pi al router y podemos hacer cosas interesantes, como ver películas con nuestro Kodi/Osmc o controlar el riego del huerto, como hace mi hermano.

See you soon.

domingo, 19 de febrero de 2017

Flash y libros digitales de las editoriales

Bueno, mis problemas con Flash han sido debido a los libros digitales que mandan las editoriales, en este caso de la editorial Oxford. Muchas editoriales siguen viviendo de las rentas con contenidos hechos en Flash, como si no se hubiesen enterado de que:


Lo malo del problema no es solo que dependan de una tecnología viejuna cada vez peor soportada como Flash, que lleva el camino de Java. Lo realmente malo es que dependan de una versión concreta del plugin, de tal forma que las nuevas actualizaciones (muchas de ellas de seguridad) del mismo hagan fallar el libro digital y para hacerlo funcionar nos obligue a tener en el sistema un Flash obsoleto.

Mi problema era con el libro "Oxford University Press/Key to Bachillerato iPack": necesita el Flash 11.2.202.394, cuando ahora vamos por la versión 24. Al abrir el libro directamente se quejaba de que no estaba instalado su Flash e invitaba a ponerlo ofreciendo un enlace. Descargar la versión de 32 o 64 bits es sencillo desde este enlace.

Claro que si lo descargamos, cogemos el libflashplayer.so de dentro y lo ponemos en la ruta /usr/lib/mozilla/plugins no habrá problemas: quedamos todo el sistema con un Flash antiguo, pero el Oxford iPack funcionará. Cuando haya alguna actualización no controlada del plugin habrá que volver a meter nuestro libflashplayer.so viejuno y así iremos tirando, pero tendremos páginas web modernas que no se vean o fallen con el Flash antiguo y las consiguientes quejas de los usuarios.

Esto no me satisfacía, así que me puse a investigar. Primeramente, me doy cuenta de que la aplicación de Oxford usa la tecnología de Mozilla llamada XUL, que se usaba para construir plugins para el navegador y, esta faceta no es muy conocida, para crear aplicaciones que son de escritorio pero internamente se basan en tecnologías Web, usando HTML, plugins, DOM, Javascript y una serie de ficheros XML. La idea es correr una aplicación web sin usar el navegador, como aplicación de escritorio.

Bueno, pues me dije: si Oxford iPack usa XULRunner (y efectivamente, en sus directorios se encuentra un libxul.so privado), internamente se basa en Mozilla-Firefox y por tanto buscará los plugins en la misma secuencia en que los busca el navegador. Esto es:
  • Directorio indicado por la variable de entorno MOZ_PLUGIN_PATH.
  • Directorio ~/.mozilla/plugins.
  • /usr/lib/mozilla/plugins, o quizá /usr/lib64/mozilla/plugins.
  • [Directorio de Perfil]/plugins, siendo normalmente el directorio de perfil ~/.mozilla/firefox/xxxx.default/.
Entonces, si antes de abrir la aplicación de Oxford hago que MOZ_PLUGIN_PATH apunte a un directorio donde está el libflashplayer.so que necesita para funcionar, esto no interferirá con el plugin instalado a nivel de sistema en /usr/lib/mozilla/plugins. Pues ciertamente es así, mi aplicación de Oxford se abría con esta ruta:
$ /home/compartido/Ingles/Oxford\ University\ Press/Key\ to\ Bachillerato\ iPack\ 1/linux/oup
siendo el ejecutable "oup" el que lanza la aplicacion XUL. Si antes de ejecutarla hago:
$ cp libflasplayer.so /home/compartido/Ingles/Oxford\ University\ Press/Key\ to\ Bachillerato\ iPack\ 1/linux/
$ export MOZ_PLUGIN_PATH=/home/compartido/Ingles/Oxford\ University\ Press/Key\ to\ Bachillerato\ iPack\ 1/linux/
$ /home/compartido/Ingles/Oxford\ University\ Press/Key\ to\ Bachillerato\ iPack\ 1/linux/oup
Ahora la aplicacion de Oxford usará la versión de libflashplayer.so que hemos metido previamente en el mismo directorio (será la 11.2, claro) y dejará tranquila la versión que hay en /urs/lib/mozilla/plugins, que seguirá siendo la 24.

Para hacer esto transparente al usuario simplemente hay que crear un script con las 2 últimas líneas y desde el fichero .desktop del escritorio que lanza el programa invocar a ese script en lugar de a "oup" directamente, modificando su línea "Exec=".

Et voilá, ya tenemos para aguantar una temporada más a Oxford y sus Flash obsoletos.

Nota: es importante que el libflashplayer.so que pongamos coincida en arquitectura con el ejecutable oup que usemos. Ambos deben ser de 32 bits o de 64 bits, no se pueden mezclar. Para saber de que arquitectura son usamos el comando "file *archivo*".


Otro problema que me relatan mis compañeros también con Oxford es que hay además libros que si aceptan el Flash 24, pero cuando van a reproducir los vídeos se queda la ventana en blanco. Parece ser que es un problema de permisos de Flash al acceder a directorios locales y se soluciona:
  • Buscando en un navegador "panel de control Adobe Flash" y pinchando el primer resultado. Nos llevará seguramente a esta página.
  • Pinchamos en "Parámetros de seguridad global".
  • Marcamos "Permitir siempre".
  • Pinchamos en Editar--> Agregar--> buscar carpeta. Le damos la ruta donde esta instalado el iPack y marcamos la carpeta "Oxford University Press" (En mi caso la ruta es "/home/compartido/Ingles/Oxford\ University\ Press").
  • Aceptamos y probamos.
Bueno, creo que con esto se resuelve la casuística que nos ha aparecido. Seguiremos informando.

viernes, 17 de febrero de 2017

Aparente bloqueo en el arranque de Ubuntu.

Es increíble, me ha pasado una vez más. Había clonado un equipo con una nueva imagen y en el arranque, tras unos cuantos mensajes, se paraba con la pantalla en negro sin mostrar ni siquiera la pantalla de login. Lo último que veía era:
Unable to determine destination address
Unable to determine destination address
Unable to determine destination address
Y, tonto de mí, otra vez he pensado que esos mensajes estaban relacionados con el "bloqueo". Nada más lejos de la realidad, esos mensajes son lo último que vemos antes de que empiece a fallar, pero la causa es normalmente otra. Como usualmente tenemos habilitado el arranque para que sea en modo gráfico y silencioso nos perdemos toda la ristra de mensajes de inicio, incluidos los que nos informan de los errores que paran el proceso de inicio.

Lo verdaderamente gracioso es que eso lo hacemos para intentar conseguir un arranque mas bonito y agradable para el usuario, con alguna animación o similar, pero la mayoría de las veces el resultado es una pantalla negra interminable hasta que sale de pronto la petición de credenciales de login. Intuyo que esa pantalla negra tiene algo que ver con el intento no conseguido de activar potentes modos gráficos durante el inicio y que el modo VESA 800x600 para mostrar una triste animación de inicio está infravalorado, motivo por el cual sólo vemos una pantalla negra. Como decía mi padre, "por querer alcanzar la gloria nos quedamos sin cielo".

Volvamos al hilo de la cuestión. ¿Cómo mostrar qué está pasando detrás del telón?. Pues editando el GRUB en el arranque:

1) Si vemos el GRUB al inicio, normalmente pulsando ESC se nos muestra.

2) Una vez en el menú, vamos a la opción que carga por defecto (normalmente la primera) y pulsamos "E" para editarla.

3) Nos salen todas las opciones y parámetros, entre los cuales estará seguramente "quiet splash". Esos dos parámetros son los culpables de que no veamos nada. Nos movemos hasta ellos con el cursor y los borramos. Puede que haya algún "vga=XX" que también interfiera, pero no lo tocaremos a no ser que esto funcione.

4) Pulsamos F10 para realizar el arranque con el GRUB modificado. Este cambio no es permanente, solo vale para el arranque actual.

Ahora sí se muestra todo el proceso y podemos ver donde se para. En mi caso era en el montaje de varias particiones que no había clonado bien, con lo cual simplemente reclonando esas particiones se ha solucionado el problema. Los mensajes mencionados antes no tenían nada que ver.

Espero que esto no me vuelva a suceder.

martes, 14 de febrero de 2017

Obtener la versión de un fichero libflashplayer.so

Estos días he estado liado con Flash Player para hacer funcionar un libro digital de Oxford, de esos que necesitan una versión concreta en una ubicación concreta para tirar sin problemas.

Llega un momento en que tienes varios libflashplayer.so de distintos orígenes dando vueltas y no sabes la versión y arquitectura de cada cual. Podemos meterlos uno a uno en el directorio /usr/lib/mozilla/plugins o similar, abrir firefox e irnos a about:plugins para saber la versión, pero es un poco tedioso.

Recordé que en Debian había un script llamado /usr/sbin/update-flashplugin-nonfree, que actualizaba libflashplayer.so si la versión de la web de Adobe era superior a la instalada. Lo he localizado en packages.debian.org y he podido localizar dentro el fragmento de código que extrae la versión de Adobe Flash del fichero .so:
# strings libflashplayer.so 2> /dev/null | grep LNX | cut -d ' ' -f 2 | sed -e "s/,/./g"
24.0.0.194
Sencillo: con "strings" se sacan todos los strings (cadenas ASCII) legibles contenidos en el fichero .so, luego buscamos una línea con el trigrama LNX y detrás está el número de versión de Flash.
Por último, ¿cómo sabemos si es de 64 o 32 bits?. Esta es más sencilla si cabe:
# file libflashplayer.so 
ELF 32-bit LSB.... | ELF 64-bit LSB....
Aprovechando el Grammy a Megadeth pongamos un vídeo suyo para rematar:



Venga, vale, no troleemos al buenazo de Mustaine: