lunes, 11 de abril de 2011

Linux: udev para varios dispositivos USB

Las computadoras de escritorio relativamente nuevas y notebooks no traen puerto paralelo. Así que una de las maneras de solucionarlo es usando una placa pci-paralelo o un adaptador USB.
El escenario y problema
Tengo a CUPS con dos impresoras conectadas al USB, una vía un adaptador a paralelo y la otra es una chorro de tinta que ya es USB. La corro de tinta es Hewlett Packard y el backend para cups es hplib así que la URI es algo como hp:/usb/DeskJet_840C?serial=NumeroDeSerie la referencia es absoluta al aparato, solucionado. Pero con el adaptador se usa el backend parallel, la URI es parallel:/dev/usblp0 y ahí empieza el problema: la HP también tiene un archivo en /dev/usblpN, y a veces le toca un N=0 y otras N=1
Implementación
La encontré con udev. En el directorio /etc/udev/rules.d/ se agregan las reglas locales para renombrar los dispositivos o crear enlaces simbólicos.
Para poder encontar algunos datos que permitan individualizar al periférico:
matias@melezca:~$ udevadm info -q path -n /dev/usblp1
/devices/pci0000:00/0000:00:12.0/usb4/4-5/4-5:1.0/usb/lp1

matias@melezca:~$ udevadm info -a -p /devices/pci0000:00/0000:00:12.0/usb4/4-5/4-5:1.0/usb/lp1

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

looking at device '/devices/pci0000:00/0000:00:12.0/usb4/4-5/4-5:1.0/usb/lp1':
KERNEL=="lp1"
SUBSYSTEM=="usb"
DRIVER==""

looking at parent device '/devices/pci0000:00/0000:00:12.0/usb4/4-5/4-5:1.0':
KERNELS=="4-5:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="usblp"
ATTRS{bInterfaceNumber}=="00"
ATTRS{bAlternateSetting}==" 1"
ATTRS{bNumEndpoints}=="02"
ATTRS{bInterfaceClass}=="07"
ATTRS{bInterfaceSubClass}=="01"
ATTRS{bInterfaceProtocol}=="02"
ATTRS{modalias}=="usb:v067Bp2305d0200dc00dsc00dp00ic07isc01ip02"
ATTRS{supports_autosuspend}=="1"

looking at parent device '/devices/pci0000:00/0000:00:12.0/usb4/4-5':
KERNELS=="4-5"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{configuration}==""
ATTRS{bNumInterfaces}==" 1"
ATTRS{bConfigurationValue}=="1"
ATTRS{bmAttributes}=="a0"
ATTRS{bMaxPower}=="100mA"
ATTRS{urbnum}=="19"
ATTRS{idVendor}=="067b"
ATTRS{idProduct}=="2305"
ATTRS{bcdDevice}=="0200"
ATTRS{bDeviceClass}=="00"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bNumConfigurations}=="1"
ATTRS{bMaxPacketSize0}=="8"
ATTRS{speed}=="12"
ATTRS{busnum}=="4"
ATTRS{devnum}=="3"
ATTRS{version}==" 1.00"
ATTRS{maxchild}=="0"
ATTRS{quirks}=="0x0"
ATTRS{authorized}=="1"
ATTRS{product}=="IEEE-1284 Controller"

looking at parent device '/devices/pci0000:00/0000:00:12.0/usb4':
KERNELS=="usb4"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{configuration}==""
ATTRS{bNumInterfaces}==" 1"
ATTRS{bConfigurationValue}=="1"
ATTRS{bmAttributes}=="e0"
ATTRS{bMaxPower}==" 0mA"
ATTRS{urbnum}=="55"
ATTRS{idVendor}=="1d6b"
ATTRS{idProduct}=="0001"
ATTRS{bcdDevice}=="0206"
ATTRS{bDeviceClass}=="09"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bNumConfigurations}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{speed}=="12"
ATTRS{busnum}=="4"
ATTRS{devnum}=="1"
ATTRS{version}==" 1.10"
ATTRS{maxchild}=="5"
ATTRS{quirks}=="0x0"
ATTRS{authorized}=="1"
ATTRS{manufacturer}=="Linux 2.6.32-30-generic ohci_hcd"
ATTRS{product}=="OHCI Host Controller"
ATTRS{serial}=="0000:00:12.0"
ATTRS{authorized_default}=="1"

looking at parent device '/devices/pci0000:00/0000:00:12.0':
KERNELS=="0000:00:12.0"
SUBSYSTEMS=="pci"
DRIVERS=="ohci_hcd"
ATTRS{vendor}=="0x1002"
ATTRS{device}=="0x4397"
ATTRS{subsystem_vendor}=="0x1002"
ATTRS{subsystem_device}=="0x4397"
ATTRS{class}=="0x0c0310"
ATTRS{irq}=="18"
ATTRS{local_cpus}=="00000000,0000000f"
ATTRS{local_cpulist}=="0-3"
ATTRS{modalias}=="pci:v00001002d00004397sv00001002sd00004397bc0Csc03i10"
ATTRS{numa_node}=="0"
ATTRS{broken_parity_status}=="0"
ATTRS{msi_bus}==""

looking at parent device '/devices/pci0000:00':
KERNELS=="pci0000:00"
SUBSYSTEMS==""
DRIVERS==""

matias@melezca:~$
Con esa información es suficiente para generar un archivo de reglas locales con esta información:
matias@melezca:~$ cat /etc/udev/rules.d/80-melezca.rules
# Creado 20110410
# Adaptador puerto paralelo para que tenga un symlink y lo tome siempre con el mismo nombre cups
SUBSYSTEM=="usb", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2305", ATTRS{bcdDevice}=="0200", SYMLINK+="usb2Parallel"
matias@melezca:~$
No elegí renombrar porque no tiene mucho sentido forzar un nombre.
El backend para la impresora queda como:
DeviceURI parallel:/dev/usb2Parallel
Y problema solucionado.
Observaciones (?)
Con udev alcanzaría para individualizar cualquier dispositivo y usar una referencia fija.
Es vital para varios dispositicos con el mismo rol en puerto USB
Referencias
http://en.wikipedia.org/wiki/Udev
http://www.reactivated.net/writing_udev_rules.html

martes, 14 de julio de 2009

Discos Duros y la mar en coche

Sucesos en los últimos 4 meses me han llevado a comprar disco duro, a cambiarlo y recambiarlo 4 veces, me hubiera gustado encontrarme alguna vez con una publicación que explique estas cosas triviales después de que uno las vive :-(

No es tan limitada la cantidad de marcas de discos

Me paso de comprar apurado no mirar y al llegar a casa encontrarme con un disco de una marca desconocida, que no tenía siquiera página web MediaMax, no soporte, no actualizaciones.

Los discos pueden fallar aunque no acusen sectores defectuosos (SMART)

La clave esta en leer los parámetos SMART, los discos contemporáneos tienen una zona reservada para reubicar sectores defectuosos, entonces al encontrar un sector defectuoso, éste se graba en la zona reservada. Un registro se incrementa en una unidad y esos datos y muchos otros se pueden leer via S.M.A.R.T. Un programa para leerlos es smartmontools y una GUI para éste es gsmartcontrol. En lo personal la GUI me parece muy cómoda, pero no lo veo cómodo para servers, las explicaciones del artículo de Wikipedia ayudan también.

dd no ayuda mucho para pruebas de fuerza bruta (secuencial vs bloque)

Dejé el 2do disco de cambio que ya era de una marca que conocía probando con lectura y escritura permanente con dd, en el disco en bruto. Sin embargo eso no alcanzó, porque aparentemente había un problema con el dimensionamiento del disco que hacía que el funcionamiento como dispositivo de bloque fallara, concretamente los problemas estaban al escribir archivos, y en la última de las particiones que me quedaba por copiar :(

badblocks -w demora y no dejarlo terminar puede dar problemas

Para probar más use badblocks escribiendo cosas, pero se demoraba tanto que lo interrumpí en alguna de las etapas, luego particioné, cree las particiones pero al momento de escribir archivos ya estaban llenas algunas de ellas? resulta que las secuencias de escrituras se confundían con alguna secuencia tipo "final" de archivo en FAT o que se yo qué que me obligó a llenar el disco de ceros nuevamente.

domingo, 14 de septiembre de 2008

Placa WireLess Realtek 8185L

La historia
Necesitaba comprar una placa wireless que sea compatible con GNU/Linux, a quién le toque se ahorra algunos varios minutos consultado: La primera lista la conocí de haber preguntado en la lista del Lugmen, pero modelo que me ofrecían no aparecía. El segundo lo conocí buscando los drivers para mi placa. Cansado entonces de tantas vueltas me decidí por una edimax EW-7326Ig con chipset Realtek.

Drivers para placa chipset Realtek 8185L
Entonces la placa en cuestión es:
 MAbeeTT@nowhere someplace/ $: lspci -nn | grep -i 8185
03:05.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL-8185 IEEE 802.11a/b/g Wireless LAN Controller [10ec:8185] (rev 20) 
MAbeeTT@nowhere someplace/ $: lspci -vv -d 10ec:8185
03:05.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8185 IEEE 802.11a/b/g Wireless LAN Controller (rev 20)
        Subsystem: Realtek Semiconductor Co., Ltd. RTL-8185 IEEE 802.11a/b/g Wireless LAN Controller
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
        Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
        Latency: 64 (8000ns min, 16000ns max), Cache Line Size: 32 bytes
        Interrupt: pin A routed to IRQ 21
        Region 0: I/O ports at cc00 [size=256]
        Region 1: Memory at fdeff000 (32-bit, non-prefetchable) [size=512]
        Capabilities: <access denied>

Tenemos varias alternativas:
  • Ndiswrapper: Ndiswrapper es un proyecto que haciendo uso de la API de los drivers para windows los implementa en el kernel linux sin emulación.

    Para hacer andar el drivers de windows bajo ndiswrapper no hay que hacer otra cosa que instalarlo, si uno quiere evadir la línea de comando alcanza con instalar ndisgtk.
    Como el driver está hecho para windows arrastra un problema propio de windows, cada cierto volumen de información transferido se interrumpe la conexión. He probado sin ninguna opción de seguridad, WPA, WPA2, WEP y es indistinto. No deja de ser una opción práctica para quien no le gusa mucho juaquear

  • Drivers de Realtek: Bajé los drivers de Realtek pero no estaba preparando las cabeceras del kernel versión 2.6.24 que viene en ubuntu 8.04 así que tiraba algunos errores de compilación. Urgando encontré éste interesante HOWTO de Will Daniels. En líneas generales lo que uno tiene que hacer es bajarse el driver del sitio de él, en la parte de los scripts de compilación se aplica un parche. Luego uno agrega los módulos a /lib/modules/ e indica los módulos a cargar en /etc/modules. Para WPA la versión de nm-applet no escribe /etc/modules/interfaces de la manera en que el driver lo necesita así que hay que seguir más pasos por acá

Futuro
Un dato interesante es que hay versiones backports del kernel en ubuntu que incluyen al driver en el paquete Debian, pero no era una opción que me entusiasme, por ahora. De hecho en kernel.org la versión 2.6.26 (y posiblemente alguna anterior) ya incluye el driver.

martes, 8 de julio de 2008

Reparación Horno Microondas

Introducción
Desde que compramos ese horno microondas nos dio problemas. En más de una oportunidad lo llevamos al servicio técnico; supuestamente le cambiaron la placa lógica en una ocasión, y en las otras dos no encontraron nada. Lo que más me sorprendió es que en la primera visita nos preguntó el Señor dónde conectaba la ficha que tiene el aparato al referirse a la ficha de 20A IRAM 2076 con espigas planas largas.

Los síntomas
Inicialmente el aparato detenía la marcha del plato giratorio y apagaba la lámpara aleatoriamente mientras cocinaba. Después de un tiempo muy largo el aparato no detenía la marcha del motor y la luz continuaba encendida, esto se solucionaba si se indicaba un nuevo programa de cocción/descongelamiento o se desconectaba al mismo del suministro eléctrico, pasado otro tiempo más largo uno conectaba lo conectaba y el motor giraba junto a la luz encendida. El punto es que mientras la gente de la garantía no se daba cuenta qué pasaba la garantía misma caducó.

El Horno
Es un Global Home KOG-393R, fabricado en Corea, garantía provista por Service New SRL. La marca no es muy conocida pero el origen y los resultados de búsqueda delataron que se trataba de algo producido por Daewoo. Buscando también me encontré con una lista de IRAM de los artefactos que daban cumplimiento a normas de seguridad varias. Allí se puede apreciar claramente que es también el mismo que en otras marcas.

Reparación:
Con el modelo quedaba buscar algunos manuales de reparación. Una cosa interesante de los manuales es que tiene todo el procedimiento de verificación de partes paso a paso en unos diagramas parecidos a los de flujo Chaplin

Probando las distintas partes nada del sector lógico fallaba, me demoré demasiado por el temor a ser 'cocinado'. Observando con el multímetro (aka tester) noté que el circuito plato-lampara-algo_mas efectivamente no se abría y que era comandado por un relé (o relay). La protección del relé era un diodo de potencia que conducía en ambos sentidos. Si por ahí tienen una fábrica de hornos microondas no compren este modelo y marca de relé. porque la marca del diodo no la pude individualizar.

Casa de electrónica; $15 el diodo y otro relé 'compatible'. Taladrito soldador, y listo el pollo para descongelar :-P.

Otra Curiosidad
Al desarmarlo noté que la chapa blanca de acero que cubre el chasis estaba oxidada por el lado de adentro. No quiero imaginar lo que sería del aparato en otro lugar del mundo con mayor humedad ambiente que Mendoza si en tan poco tiempo por aca ya está (parcialmente) oxidado.

domingo, 20 de enero de 2008

Primeros adornos Open Source

Este sábado me sorprendió una llamada al teléfono celular, resultó ser Santiago, "tengo algo para vos que creo que te va a gustar". En el viaje la intriga me incomodaba.

La sorpresa fue más grande cuando me tocó abrir el paquete:

Resulta que en su trabajo (Lugar en el que yo trabajé tambíen) habían pasado unos desarrolladores de Mozilla (traductores para ser más precisos). Mi amigo les adoró los pines de la mochila, entonces le dejaron algunos y la pulserita.

Esta tarde pensaba que estos son mis primeros addons del mundo material. Desde hace mucho tiempo he querido dar con las remeras del LugMen pero no se han dado las condiciones de dinero ni presencia.

Otra observación es que yo uso de manera predilecta Debian: ¿cómo es que tengo logos propietarios conmigo?. Pero bueh... no se puede cumplir con todas al mismo tiempo.

De nuevo: Gracias Santi.

domingo, 16 de diciembre de 2007

Scripts para saber cuando pasa cada hora:

Suele suceder que gracias a la gran estabilidad de los sistemas que usamos y la adictividad las terminales gráficas, virtuales, de texto algunos perdemos la noción del tiempo.

Como suelo usar varias veces la compu con los parlantes encendidos para escuchar música de vez en cuando lo que se me ocurrió hacer es un conjunto de scripts que combinados con crontab, un reproductor de sonido y un archivo de audio al inicio de cada hora hicieran un toque horario parecido al de las radioemisoras AM.

La idea es que no se interrumpa la música ni lo que se oye sino que se "pise" el sonido de los beeps con lo que corre. Esto lo he logrado gracias a los drivers ALSA para mi placa de sonido, mi placa de sonido y otras cosas que desconozco que permiten que dos programas salgan al mismo tiempo (mixer por hardware debería ser).

Lo primero que se me ocurrió hacer fue el sonido de Beep, después de instalar audacity y probar varias cosas noté que lo mejor era aprender a usar bien el programa y luego grabar de un buzzer que tengo guardado por ahí. Lo que quedó fueron tres toques: uno por canal derecho el otro por el izquierdo y al final el más largo por los dos canales, de paso el archivo me sirve para probar las conexiones de sonido. Naturalmente lo exporté a Ogg Vorbis.

Pensé en un script que verificara si el usuario dueño del proceso estuviera logueado, que leyera un archivo de configuración que evitase la ejecucióon en determinadas ocasiones y que en sí mismo tuviera la información del archivo de sonido y el programa para escucharlo. Luego se me ocurrió que el programa y el archivo podrían ser enviados como argumentos. Y luego le agregué como escribir el archivo de configuración.

Agregué las lineas correspondientes a crontab que ejecutasen el escript a los 00 minutos de cada hora. Y queda una cosa más o menos:

00 * * * * nice -n10 sh /home/MAbeeTT/myFilesystem/my_usr/my_share/my_bin/beep_horario.sh \
/usr/bin/ogg123 /home/MAbeeTT/myFilesystem/my_usr/my_share/beeper/Beeper.ogg \
2>/dev/null 1>/dev/null

TOdo en una linea, claro. Como se puede apreciar el script se ejecuta amablemente con un valor nice 10, llama a ogg123 que leerá el archivo Beeper.ogg. Esa aparentemente extraña organización del directorio myFilesystem es una forma personal de evitar ensuciar /usr/local con programas y scripts que solo correrá mi usuario.

En definitiva la ejecución del sript sería:

sh beep_horario.sh programa archivo [Valor_permiso_permiso_escritura]
donde Valor_permiso_permiso_escritura podría ser un 1 o cualuier otra cosa para escribir el archivo de configuración ~/.beep_horario y habilitar o deshabilitar la emisión del sonido.

Pero luego se me ocurríó que sería más interesante hacer un script que agregase las sentencias por sí solo y lo agregué, al mismo se le entrega:

sh instalar_cron.sh programa archivo_audio archivo_temporal valor_nice

Donde programa podría ser ogg123, archivo_audio algún archivo de sonido (poque tal vez no les guste mi Beeper.ogg), archivo_temporal un archivo temporal para que no se pierda la informacion de crontab y valor_nice deber ser el valor nice del proceso, está forzado a ser mayor 4.

Todo esto está disponible en el archivo de descarga

Después de algnos días me econtré en Debian con algunos paquetes parecidos:

  • saytime: speaks the current time through your sound card. Say the current time through your sound card. Requires you have a sound output device available.
  • grandfatherclock: a clock that tolls time acoustically grandfatherclock plays audio files to report the time. The default configuration emulates a grandfather clock with Westminster chimes. Cuckoo clock and Close Encounters of the Third Kind files are included as well...

domingo, 9 de diciembre de 2007

Escuchando múscica con MPD III - Ahora icecast

Antes les expliqué Cómo instalar mpd, y luego algo de usarlo en modo usuario. Ahora les muestro lo que encontré y configuré probando un poco: icecast.

La idea:

Icecast es un servidor de streamings que soporta Ogg Vorbis y Mp3. Mi idea es usarlo como un elemento de interfaz entre la supuesta computadora del armario y un cliente que dispondría del los parlantitos, que podría ser un laptop o un desktop, que podría estar dentro una red local o bien Internet. Para Icecast mpd sería un cliente fuente (source client) y el programa que corre en la computadora laptop sería un oyente (listener), que puede ser mplayer, xmms, rhythmbox, winamp.

Debo agregar unos parámetros al archivo de configuración de mpd:


################# SHOUT STREAMING ########################
#
# Set this to allow mpd to stream its output to icecast2
# (i.e. mpd is a icecast2 source)
#
audio_output {
        type            "shout"
        name            "my cool stream"
        host            "localhost"
        port            "8000"
        mount           "mpd.ogg"
        password        "hackme"
#       quality         "5.0"
        bitrate         "128"
        format          "44100:16:2"

# Optional Paramters
        description     "here's my long descriptiion"
} # end of audio_output

De los parámetros:

  • type: es el tipo de salida DEBE ser shout.
  • name: es el nombre que tendrá el stream
  • port: puerto que usará icecast, yo escogí el 8000 porque tengo un apache para experimentos, pero podría tenerlo andando en el 80 o cualquier otro.
  • mount: es el punto de montaje del streaming, para acceder al streaming se usará luego ip_del_servidor:puerto/mounto_montaje.ogg. Escogí ponerle extensión .ogg al punto de montaje porque algunos programas clientes se atontan sin la extensión.
  • password: para que icecast no le de lugar a cualquier persona.
  • quality: calidad de codificación del stream Ogg es valido cualquier vvalor con un decimal entre 0 y 10. Solo vale poner el parámetro quality o bitrate; pero no ambos.
  • bitrate: el bitrate de encodeo en kbps.
  • format: usa la forma sample_rate:bits:channels donde sample_rate es el nivel de muestreo, bits los bits por muestreo y channels el número de canales.
  • description: la descripción del streaming.

Hasta ahora los datos colocados en description y name sólo se ven en la interfaz web de icecast.

Como es lógico mientras mayor es la calidad de salida más ancho de banda consumido, más recarga de la red y más uso de CPU.

Icecast

Por otro lado hay que instalar icecast:

apt-get install icecast2

La configuración de icecast es sencilla, el archivo de configutación es /etc/icecast2/icecast.xml, al menos se puede dejar algo andando sin tocar demasiadas cosas, me basé en el archivo que viene en el paquete Debian icecast_minimal.xml:

<!-- This config file contains a minimal set of configurable parameters,
     and mostly just contains the things you need to change.  We created
     this for those who got scared away from the rather large and heavily
     commented icecast.xml.dist file. -->
<icecast>
    <limits>
        <sources>2</sources>
    </limits>
    <authentication>
       
<source-password>hackme</source-password>
       
<relay-password>hackme</relay-password>
        <admin-user>admin</admin-user>
       
<admin-password>hackme</admin-password>
    </authentication>
    <directory>
       
<!--  <yp-url-timeout>15</yp-url-timeout> -->
       
<!-- <yp-url>http://dir.xiph.org/cgi-bin/yp-cgi</yp-url> -->

    </directory>
    <hostname>localhost</hostname>
    <listen-socket>
        <port>8000</port>
    </listen-socket>
    <fileserve>1</fileserve>
    <paths>
        <logdir>./log</logdir>
        <webroot>./web</webroot>
        <adminroot>./admin</adminroot>
        <alias source="/"
dest="/status.xsl"/>
    </paths>
    <logging>
       
<accesslog>access.log</accesslog>
        <errorlog>error.log</errorlog>
        <loglevel>3</loglevel>
<!-- 4 Debug, 3 Info, 2 Warn, 1 Error -->
    </logging>
     <security>
        <chroot>0</chroot>
        <changeowner>
            <user>icecast2</user>
            <group>icecast</group>
        </changeowner>
    </security>
</icecast>

Se puede hacer una configuración más completa: con una contraseña por cliente fuente, limitar la cantidad de oyentes por fuente, etc.

Como se puede ver está la misma contraseña para el server y como pueden apreciar también no me tomé la seguridad en serio ya que sólo estoy experimentando.

Icecast tiene una interfaz web cuyo usuario y contraseña están en el archivi de configuración, a través de ella se puede ver las estadísticas del servidor, echar clientes, cambiarlos de canal

Para que cada vez que arranque la computadora del armario corra todo esto automáticamente al inicio del sistema alcanza con tocar los archivos /etc/default de los paquetes correspondientes.

Para elegir la lista, cambiar de temas, etc alcanza con cualquier cliente de mpd y con la configuración que permita al cliente acceder al comando de la lista

Varias salidas al mismo tiempo.

Una cosa interesante es que se pueden tener activas más de una salida al mismo tiempo; por ejemplo se puede tener la salida ALSA lista y al mismo tiempo la salida para icecast. Algunos clientes como gmpc permiten activar o desactivar cada una de las salidas

Referencias: