Robots y modelos

Notas sobre pruebas, modelado y aventuras en Java y Android

Running UML-RT models on a Raspberry Pi-based rover

with one comment

Last year, I joined the Papyrus Industry Consortium to help push forward the development of Eclipse Papyrus, one of the most actively developed open-source UML environments currently. The Papyrus IC consortium is working towards increasing the use of Papyrus for teaching, research and industrial use. Among those activities, they decided to provide a limited number of rovers for these purposes, and I applied for one with the goal of attracting some of my students to the idea of model-driven software engineering (MDSE).

After my return from MoDELS’17 (and the excellent tutorial on Papyrus-RT there), I spent the odd hours here and there getting the Rover example project from its supporting material to run, and making some adjustments (which are now on Github). It took a while and a good bit of trial and error, so I thought I might as well do a write-up in case somebody may find it useful :-). I’ll talk about the rover first, then present a high-level view over the UML-RT models, and finally dive into the setup of the Pi and the PC.

Lee el resto de esta entrada »

Written by bluezio

17 de octubre de 2017 at 19:18

Publicado en Uncategorized

Building a custom GH60 keyboard

leave a comment »

diy-keyboard

I have always been a big fan of mechanical keyboards: the feel is completely different and much more satisfying than what you get from typical membrane keyboards. Since 2011, I’ve had at home a Filco Majestouch 2 that I bought at the Keyboard Company. Particularly, a tenkeyless (no numpad) tactile version with Cherry MX Brown switches. Still as good as new after all these years!

So far, I only had one for home, and at work I was using the (admittedly quite good) keyboard of my Thinkpad X1 laptop. While it’s decent, it wasn’t quite as nice as a mech keyboard. I could have bought a pre-made one, but that would have been no fun :-). Instead, I teamed up with Peter Lewis (a fellow Lecturer at Aston) to build our own.

Lee el resto de esta entrada »

Written by bluezio

8 de octubre de 2017 at 14:24

Publicado en Uncategorized

Soluciones de acceso remoto desde un Nexus 7 para Windows y GNU/Linux

leave a comment »

Estos días he estado preparando la red de casa para poder acceder remotamente a los ordenadores desde cualquier sitio usando mi tableta Nexus 7. Tras probar unas cuantas cosas, al final he conseguido montar varias soluciones para poder administrar mis máquinas mediante terminales y escritorios remotos y encender mis ordenadores.

Lo dejo todo anotado por aquí por si a alguien le sirve :-). Empezaré contando las opciones gratuitas que hay (aunque requieren trastear), y acabaré hablando de varias opciones que no requieren tanto trabajo (aunque tampoco me resuelven el 100% de los problemas).

OpenVPN: conexión segura a la red de casa

Lo primero que se le pasaría a cualquiera sería abrir puertos a mansalva en su router y entrar a fuego con cualquier programa de acceso remoto tras asegurarse de que el router tenga un nombre fijo asociado a la IP que tengamos en cada momento, usando un servicio como no-ip.com.

Esto, sin embargo, plantea varios problemas:

  • Es un incordio tener que mantener las asociaciones entre los puertos del router y los puertos concretos de cada máquina, y muy propenso a errores.
  • Cada puerto abierto es una vulnerabilidad potencial, y si alguien se cuela por ella se puede colar en todas tus máquinas a la vez. Es necesario que haya el mínimo número de puertos abiertos al exterior, y que lo que esté detrás del puerto esté *muy* bien protegido.

En vez de eso, una opción mucho mejor es crear un túnel cifrado a través de Internet a la red a controlar, de forma que parezca que estamos en esa misma red y podamos acceder a todos los ordenadores como si nada. Para ello se ha de instalar un servidor VPN (Virtual Private Network) en la red a controlar, en un ordenador que esté siempre encendido y que sea visible desde el exterior (con el nombre fijo de no-ip.com, por ejemplo). El candidato ideal para todas estas cosas es el router, precisamente :-D. La mayoría de los routers domésticos no incorporan esta funcionalidad, pero si tienes un router compatible con algunas de las variantes más recientes de Tomato (como la de Toastman, basada en TomatoUSB) puede instalársela y aprovechar el servidor OpenVPN que tienen incorporado. Mi (algo vetusto) WRT54GL es uno de ellos: si queréis compraros uno, quizás os venga mejor el ASUS RT-N16 e EasyTomato.

La mayor complejidad a la hora de montar una VPN con OpenVPN es configurar la autenticación de los usuarios. Aunque se admite la posibilidad de usar un simple par usuario/contraseña (una «static key«), esto no funciona bien cuando hay que darle permiso a varios ordenadores. Es mucho mejor utilizar certificados X.509 (como los de SSL) para autenticar tanto al servidor como al cliente, pero gestionar los certificados (lo que se llama la «Public Key Infrastructure» o PKI) es bastante complejo si no se tienen conocimientos previos. Para esto existen programas que simplifican todo el proceso. Probé XCA (no me convenció la interfaz) y TinyCA (no funcionaba en Arch Linux), así que al final utilicé EasyRSA, un conjunto de guiones Bash del proyecto OpenSSL en el que se basa el cifrado de OpenVPN. Funcionan muy bien, aunque tuve que tirar todas las claves varias veces hasta que quedaron como me gustaron :-). El proceso es básicamente el siguiente:

  • Editar el fichero «vars» de EasyRSA apropiadamente.
  • Generar el fichero de parámetros de Diffie-Helman, que se usarán para generar todas las claves privadas y públicas.
  • Generar el par de claves de nuestra Certification Authority.
  • Generar el par de claves de nuestro servidor OpenVPN (el Common Name debería coincidir con el nombre público del servidor).
  • Generar un par de claves para cada cliente OpenVPN (hay que usar –interact para poder poner el Common Name de cada cliente).

El siguiente paso es configurar el cliente. En el caso de Android, OpenVPN tiene un cliente oficial, aunque el que estoy usando (y con el que me va bien, así que para qué cambiar :-D) es el de Arne Schwabe. Por cierto, este último ya no requiere root desde Android 4.0, creo, ya que utiliza un API estándar de Android. En general, con seguir los pasos que da la aplicación irá bien, aunque tendréis que toquetear un poco hasta que termine de funcionar. Un pequeño problema que yo tuve fue en el detalle del enrutado. Mi router neutro está detrás de un módem+router del que es destino por omisión para todas las conexiones entrantes (DMZ), y esto en general funciona bien para las conexiones TCP. Sin embargo, no es así para las conexiones UDP, que son las que usa OpenVPN por omisión: tuve que poner explícitamente un mapeo de puertos hasta que funcionó bien.

Con esta conexión pude sacar otro beneficio: poder entrar en la interfaz web de mi router y usar sus funciones de Wake-on-LAN (también cortesía de Tomato) para encender remotamente mis ordenadores. La clave para poder hacer esto es que estén conectados por cable al router, y que tengan debidamente configurada la BIOS para admitir esta forma de encendido. Esto varía de ordenador a ordenador, así que no puedo dar mucha más información :-/. Si todo va bien, con un clic enciendes el ordenador, te esperas un minuto o dos e inicias sesión por alguno de los métodos inferiores.

OpenSSH y JuiceSSH: terminales remotas

Con la VPN permitiendo a nuestra tableta ser parte de la red de casa, lo siguiente es ver cómo abrir una terminal (texto puro y duro) a una de las máquinas. Esto es muy eficiente y requiere muy poco ancho de banda, y es ideal para administrar sistemas remotamente. El protocolo ideal para estas cosas es SSH (Secure SHell), y para ello necesitaremos instalar un servidor SSH en la máquina a la que nos vayamos a conectar (el de OpenSSH es estupendo), y un cliente SSH en la tableta.

En Android hay unos cuantos clientes SSH. Originalmente usaba ConnectBot, pero hace unos meses me cambié a JuiceSSH, que en mi opinión tiene una interfaz muy superior. Hay una versión de pago, pero con la versión gratuita vais sobrados. Por cierto, no olvidéis usar Byobu para multiplexado de sesiones (o por lo menos tmux) si os conectáis a una máquina con Ubuntu.

Otro uso para SSH es como túnel para protocolos inseguros, como VNC (cuando se usa sin cifrado), que veremos a continuación.

TightVNC, TigerVNC, x11vnc y bVNC: pantallas compartidas remotas

El siguiente paso era conseguir acceso a un entorno gráfico. Básicamente, hay dos protocolos estándar para esto: RDP (Remote Desktop Protocol, el «escritorio remoto» de Windows) y VNC (Virtual Network Computing). RDP viene de serie en muchas versiones de Windows (en Linux no es tan popular: existe xrdp pero es peliagudo de configurar), permite transmitir el audio del ordenador remoto y es muy eficiente y flexible, pero tiene la pega de que al iniciar sesión remotamente se cierra la sesión local. Si tienes que darle soporte a un familiar, no le va a hacer gracia que su música o su partida de GranjaPueblo se interrumpa mientras le arreglas el cacharro :-D.

Por eso, prefiero VNC, que permite «compartir» la pantalla, con lo que la otra persona podrá ir viendo todo lo que vas haciendo. Al igual que con SSH, necesitaremos instalar un servidor en el ordenador a administrar y un cliente en la tableta.

El servidor a usar depende mucho del sistema operativo. Para Windows, el mejor (de los gratuitos) que hay ahora mismo es TightVNC 2.6. Se puede instalar como un servicio, de forma que esté disponible incluso antes de iniciar sesión, y es muy fácil de montar. De hecho, veremos que es el que te instala JumpDesktop cuando le pides acceso por VNC en Windows. TightVNC hereda de las versiones de código abierto de RealVNC, que se publicaron bajo la GNU GPL.

Para Linux, podríamos también usar TightVNC, pero sería una versión demasiado antigua (la 1.3). En este caso es mucho mejor trabajar con TigerVNC 1.2, un fork de TightVNC con mejor soporte para Linux. TigerVNC permite abrir un servidor X virtual al que conectarse remotamente por VNC como si fuera una pantalla normal y corriente: sólo tenemos que establecer la contraseña con «vncpasswd», abrir el servidor con «vncserver» desde una sesión SSH y listo.Si lo que queremos es conectarnos a una pantalla «de verdad» en una sesión ya abierta, tendremos que usar x11vnc. Es un poco más complicado de usar, pero no mucho más. Tendremos que ejecutar una orden como ésta desde una sesión SSH, y luego ya podremos entrar con el cliente oportuno:

x11vnc -rfbauth ~/.vnc/passwd &

Un aspecto molesto de Linux que no he podido solventar aún es cómo entrar por VNC sin haber iniciado sesión, como se puede hacer en Windows. La solución que he adoptado por lo pronto es entrar automáticamente en mi cuenta de usuario e inmediatamente bloquear la pantalla por contraseña de forma automática, usando las opciones de KDE 4. Para no tener que abrir el servidor VNC yo, he añadido esta línea al final de ~/.xprofile:

x11vnc -rfbauth ~/.vnc/passwd -forever &

La opción «-forever» evitará que se cierre el servidor VNC cuando cierre mi sesión en algún momento. De esta forma, puedo encender remotamente mi ordenador y luego entrar a una sesión remota sin más.

Con los servidores resueltos, el siguiente paso es seleccionar un buen cliente VNC para Android. Primero probé el que tiene más solera de los gratuitos, androidVNC, pero no me gustó demasiado la interfaz: era bastante primitiva, la verdad. Tras mirar un poco, en un hilo de comentarios vi al autor de bVNC promocionar su aplicación, y tras probarla creo que es muchísimo mejor, y que se merece más instalaciones. El manejo es más cómodo, y permite compartir fácilmente el portapapeles, cambiar de modo de color sobre la marcha y desplazarse por la pantalla, además de implementar más opciones de seguridad, como SSL anónimo o túneles SSH. Lo único que me costó trabajo fue averiguar cómo hacer clic derecho, pero mirando la ayuda se resolvió todo.

JumpDesktop: pantallas compartidas y escritorios remotos seguros sin VPN

De todos modos, la verdad es que estaba algo molesto con la dificultad en bVNC a la hora de hacer clic sobre ciertos elementos pequeños, la imposibilidad de dejar «flotar» el cursor sin hacer clic y otros detalles varios de la interfaz. Son cosas menores, pero me puse a buscar clientes VNC mejores. Y tras hacerlo, di con JumpDesktop: un cliente RDP y VNC con mejor acabado aún, aunque de pago (unos 7,5€  a fecha de hoy). Un detalle aparentemente tonto es que ahora el cursor se puede manejar con una «lupa» que tiene debajo, permitiendo dejar flotando el ratón sobre un punto dado y apuntar con mucha más exactitud y comodidad. El botón derecho es mucho más sencillo de introducir, además :-D. JumpDesktop parece estar en desarrollo activo: hace poco han sacado una versión con soporte para los gestos multitouch de Windows 8.

El precio sería un tanto alto si no fuera porque tiene otra ventaja: puede operar a través de NAT y cortafuegos sin necesidad de montar una VPN. Yo ya tenía montada mi VPN, pero la verdad es que me intrigó bastante de cara a otras posibilidades. Tienes que instalar un software específico en cada máquina con Windows o Mac (lástima, nada para Linux) e introducir las credenciales de una cuenta de Google en cada una. Esas credenciales no se mandan a JumpDesktop, sino que se usan para iniciar sesión en Google Talk y utilizar el protocolo XMPP en que se basa Talk para establecer la conexión VNC o RDP oportuna. Lo probé con varias máquinas y funcionó estupendamente, así que no me arrepiento demasiado del gasto :-D. Las contraseñas se guardan localmente en cada dispositivo y no se mandan a JumpDesktop, así que si hay que fiarse de alguien es de Google.

Pero, por si acaso, me dió por mirar la competencia, y encontré otras dos opciones parecidas que también se saltaban NAT y cortafuegos: Splashtop y TeamViewer. Las dos son gratuitas para uso personal, y luego ofrecen productos de pago para uso profesional. Por mi parte bien: probé Splashtop y su Streamer no me funcionó bajo Arch Linux, así que lo descarté inmediatamente.

TeamViewer sí funcionó bastante bien en Linux. El problema es la aplicación para Android, que no es tan buena como la de JumpDesktop. Mover el ratón exige arrastrarlo por toda la pantalla de forma bastante irritante, y no se pueden usar las flechas de mi teclado Bluetooth ni las combinaciones de tipo Ctrl+X o Alt+Y. Además, la aplicación y el servicio eran propensos a cuelgues y corrupción de su base de datos interna si cerrabas e iniciabas sesión con cierta frecuencia (normal durante mis pruebas), y no respetaban bien la multitarea de Android. En general, JumpDesktop me resultó más agradable de usar, y al estar basado en estándares, la falta de un cliente Linux no es importante: uso OpenVPN y luego abro el cliente VNC o RDP que prefiera :-D. De todos modos, TeamViewer tiene una importante ventaja si tenéis que dar soporte a otras personas: no requiere introducir nuestras credenciales en las máquinas que vayamos a controlar. Cada máquina tiene asignado un número, y cada vez que lanzamos TeamViewer se nos genera una contraseña de un uso. El dueño de la máquina a controlar nos puede dar ambos datos por teléfono, nos conectamos, resolvemos el problema y listo. Esto puede ser crucial en ciertas situaciones. Otra ventaja es que incorpora transferencia de archivos entre la tableta y la máquina remota, que en otros casos puede venir bien.

Resumen

Mis recomendaciones personales son más o menos las siguientes:

  • Todo basado en estándares y software libre: Tomato, OpenVPN (servidor+cliente VPN), OpenSSH (servidor+cliente SSH), TightVNC, TigerVNC, x11vnc y bVNC. Lo cubren todo, son BSD o GPL y encima gratis. La pega es que requieren bastante configuración inicial. Hay clientes mejores que bVNC como JumpDesktop (aunque son cerrados y de pago).
  • Acceso RDP a través de NAT y cortafuegos sin usar VPN, usando credenciales de Google: JumpDesktop. Quizás lo de dar las credenciales de Google duela mucho menos si usas las claves específicas de aplicación que da Google al activar autenticación de doble factor. Estas contraseñas se pueden revocar automáticamente cuando ya no las necesites, y no valen para acceder a las partes más sensibles de la cuenta.
  • Acceso VNC a través de NAT y cortafuegos sin usar VPN: JumpDesktop con credenciales de Google o TeamViewer con claves permanentes o de un solo uso. TeamViewer tiene más funcionalidad y cliente Linux, pero JumpDesktop tiene mejor acabado en Android.

Tengo entendido que Splashtop es mejor para videojuegos, pero no pienso usar el acceso remoto de esa forma, así que no me he molestado mucho más con ello :-D.

Written by bluezio

18 de marzo de 2013 at 3:10

Publicado en Uncategorized

Reemplazando java.util.Random por el Mersenne Twister

leave a comment »

Esta mañana un compañero me mandó un enlace sobre la (mala) calidad del generador de números pseudoaleatorios que viene con la biblioteca estándar de Java: la clase Random. Ya había oído cosas acerca de que era malo, pero esto lo dejó bastante claro:
 
http://www.alife.co.uk/nonrandom/
 
La cosa es que no debería verse un patrón en la imagen que genera la applet, y además se repite con bastante facilidad. Java dispone de otra implementación mejor (SecureRandom), pero tiene dos pegas:
  • No puedes saber con total seguridad qué proveedor se está usando, ya que depende de lo que venga de serie en la JVM. Si quieres uno concreto lo puedes indicar por nombre, pero entonces te atas a una JVM determinada.
  • setSeed(…) no reinicia el algoritmo con la nueva semilla, sino que alimenta a la semilla existente con la nueva información. Dado que SecureRandom es para uso criptográfico más que para simulaciones, no es mala idea, pero yo necesito que los resultados sean los mismos siempre que ponga la misma semilla :-/.

Por ello, tuve que descartar SecureRandom también, y la única opción era buscar un PRNG bueno en alguna biblioteca externa. Mirando un poco encontré Uncommons Maths, una biblioteca escrita en Java puro de sólo 50KB y bajo la ASL 2.0, que encima superaba la batería Diehard (que parece ser una buena referencia en el mundillo de los PRNG). Según este hilo de Stack Overflow, los resultados del autor original son reproducibles y j.u.Random no cumple esa batería de pruebas.

Por lo pronto he pasado uno de mis programas de Random al MersenneTwisterPRNG (una implementación del Mersenne Twister de Matsumoto y Nishimura), que es el recomendado por el autor para simulaciones de propósito general. Ha sido más fácil de lo que esperaba, ya que todos los PRNG de Uncommon Maths heredan de Random, así que es un sustituto limpio. Y por si no fuera poco, Uncommon Maths también implementa algunas distribuciones comunes de probabilidad (normal, Poisson, exponencial y binomial por lo menos) e incorpora PRNG con más rendimiento (basados en operaciones lógicas XOR) o con más seguridad (AES). Está muy completa la biblioteca :-).

Written by bluezio

16 de enero de 2013 at 0:14

Publicado en Uncategorized

Tagged with

Mis impresiones del Apache Barcamp Spain 2012

with 6 comments

Ayer tuve la oportunidad de asistir al Apache Barcamp Spain, que se celebró en la Escuela Técnica Superior de Ingeniería Informática de Sevilla. Por cierto, no la visitaba desde el II Concurso Universitario de Software Libre, y me alegró ver otra vez a Ana Rey, una de sus organizadoras. Iba desde Cádiz junto con Francisco Pérez (fundador de CadizDevelopers y conductor del coche compartido), Cayetano Soriano (antiguavíctima alumno y sufrido organizador de las Betabeers de Cádiz) y Francisco Peregrino (no estoy seguro del apellido: ¡perdona si me equivoco!).

El evento comenzó pasadas las 10:00, con una presentación general del evento y los patrocinadores:

  • BitNami, que además de proporcionar instaladores fáciles con pilas de tecnologías comunes como WordPress, Joomla, Drupal o Redmine, tienen su propia infraestructura cloud por si nos queremos ahorrar montar y mantener el servidor. La verdad es que no sabía que eran españoles, y daban unas camisetas muy simpáticas, por cierto ;-).
  • CodeBusters, una empresa de consultoría sevillana basada en código abierto con mucha gente de la Apache Software Foundation.
  • Deiser, a los que les debo la entrada (tardé demasiado y se acabaron las entradas :-S). Se especializan en soluciones para desarrollo ágil y cooperativo, con plugins para Sparx Enterprise Architect y Atlassian JIRA entre otras cosas.
  • Koliseo, el proveedor de venta de tickets utilizado para la Barcamp.
  • Novayre, una empresa que trabaja mucho con las líneas de arquitecturas orientadas a servicios y procesamiento de eventos complejos que tenemos en el grupo. Novayre también participó en la organización de Sistedes 2012, un evento académico al que asistí esta misma semana. Tuve el placer de conocer a su director gerente Víctor Ayllón en la cena de gala de Sistedes 2012, y me comentó muchas de las prácticas punteras que tienen en Novayre. Pude coincidir con él ayer también y conversar un rato más.
  • Zaizi, integrador premiado de Alfresco, de Ephesoft y de eXo.

Algunos de los colaboradores del evento fueron la gente de Klicap, los desarrolladores de Clinker, un ecosistema virtualizado de desarrollo de software que estamos evaluando en la Universidad de Cádiz, y de cuyas imágenes he aprendido un par de trucos que he adaptado a los servidores que llevo manualmente :-). Tuve la oportunidad de desvirtualizar a Manuel Recena, uno de sus desarrolladores principales, y se ve que van a toda vela con el proyecto.

Desconocía la organización de los Barcamp, y me ha parecido curiosa en tanto que era bastante distinta de las usuales conferencias. Al registrarte en la entrada, te daban una tira de pegatinas y una ficha de póquer. En el acto de apertura se presentaron todos los candidatos para dar charlas, y la gente usó sus pegatinas para votar a las ponencias que más les interesaran. A continuación, las ponencias se filtraron y ordenaron por votos y se dividieron en tres tracks paralelos.

Tras el primer «coffee break» del día (en una sala algo apretada para mi gusto, he de decir), asistí a estas ponencias:

  • Una introducción a CoffeeScript, un lenguaje traducible a JavaScript que evita muchos de sus problemas y es en general mucho más fácil de leer y escribir. Me pareció muy interesante el enfoque general, y el lenguaje parece bastante más cómodo que JS. Una cosa simpática es que la forma en que implementa el ámbito léxico de las variables consiste básicamente en crear clausuras que envuelven a la variable original. La gente preguntó bastante cómo integrar CoffeeScript con código JavaScript ya existente, pero viendo que al final se compila a JavaScript no creo que haya mucho problema.
  • Herramientas de desarrollo web, en que el ponente explicó muchas funcionalidades ocultas (por lo menos, lo eran para mí) de Chrome útiles para desarrolladores web, contó de qué iban LESS y SASS (lenguajes compilables a CSS que facilitan ciertas cosas y ayudan a respetar el principio DRY) y enseñó algunas de las cosas que puede hacer Sublime Editor. Sublime es el editor de moda, y reconozco que está bastante bien para ciertos lenguajes. Para Java, sin embargo, sigo creyendo que las mejores opciones son Eclipse (por su extensibilidad) e IntelliJ (por su pulido e «inteligencia»). Además, ambas son de código abierto (aunque IntelliJ tiene extensiones «premium»).
  • BDD con JavaScript, en que el ponente enseñó cómo hacer BDD con los frameworks Jasmine y Casper sobre una aplicación que ayudaba a usar la técnica Pomodoro(que desconocía), y anunció que publicaría algunos de sus componentes como código abierto.Aunque la charla estuvo bien, la vi demasiado centrada en código. En particular, Jasmine me pareció que mezclaba el código con la historia: por lo que he visto, Cucumber parece mantener una mejor separación entre la historia de usuario y la prueba en sí. Casper provee un navegador automatizable sin interfaz: Cayetano me mencionó ZombieJS, otro entorno parecido a Casper, y Behat, que parece el equivalente de Cucumber en PHP. Discrepo de su afirmación de que BDD sea lo mismo que TDD: para mí, uno se centra en historias de usuario (y produce pruebas funcionales o de integración), y otro en unidades específicas de código y su comportamiento esperado. En mi opinión hacen falta ambos, ya que puede haber «corner cases» que sean difíciles de probar con historias, y una prueba unitaria no cubre tanto código como una historia.

Aquí paramos y nos fuimos a almorzar al Sloppy Joe’s que había cerca. Si vais, recordad que la «pizza pequeña» es para 2 y la «mediana» supongo que para 3 :-D. El resto de ponencias (con otro «coffee break» intercalado tras la primera) fueron:

  • Git avanzado: antes de seguir, he de decir que he dado unos cuantos cursos y talleres de Git por mi cuenta, y que tengo materiales y enlaces por aquípara el que los necesite ;-). En este taller enseñaron cómo replantear una rama en base a otra («rebase» y su versión interactiva), las dos formas básicas de reunir ramas, con «fast-forward» o una nueva revisión de reunión («merge commit») y los diversos tipos de «reset» (blando, duro y mixto). También hablaron un poco del modelo interno de datos de Git y detallaron algunas cosas como que git-foo se convierte a «git foo» si está en el PATH. La idea de poner el log debajo para que se vean los cambios de HEAD y las nuevas revisiones me pareció muy buena.Dicho todo esto, considero que el título de «Git avanzado» es un tanto discutible. No me imagino a un usuario de Git que no tenga que hacer reuniones de ramas o replantear ramas en base a otras, por ejemplo. De todos modos, entiendo que con las restricciones de tiempo disponibles era lo mejor que se podía hacer. Supongo que «Git básico» no tendría el tiempo suficiente para ver esos conceptos. Como usuario común de Git, me habría gustado mucho que discutieran algunas cosas más recientes, como «git notes», o algo más ocultas, como «git add -i», «git grep», «git bisect», «git mergetool», o «git bundle».
  • Karmacracy: esencialmente, fue un caso de estudio en que explicaron cómo habían conseguido que Karmacracy escalara a millones de peticiones utilizando las tecnologías cloud de Amazon. Fue bastante interesante ver todo lo que Amazon tenía que ofrecer, y cuánto costaría en un despliegue típico. Otro aspecto importante fue que Amazon no te da esa escalabilidad mágicamente: aprovecharlo exige mucho diseño previo y planificación.
  • Push & Pull: en esta charla se describieron las distintas tecnologías que se habían estado usando para pasar del típico modelo petición->respuesta del paradigma cliente-servidor a una comunicación bidireccional en que tanto el cliente pudiera solicitar información en un momento dado («pull») como que el servidor le enviara notificaciones sin esperar a que el cliente las pidiera («push»). Mencionó el antiguo sistema basado en consultas periódicas («polling»), los plugins de navegador (Java y Flash), el «long polling» de Comet, los «server-sent events» de HTML5 y los Web Socketsde HTML5, comparando las ventajas y desventajas de cada uno.A nivel didáctico me gustó mucho la charla, pero habría preferido aligerar la discusión de las alternativas y enseñar con un ejemplo sencillo cómo se utilizarían los Web Sockets a nivel de código. Un detalle simpático fue su comentario de que los Web Sockets funcionaban especialmente bien a través de SSL, ya que los cortafuegos no se molestaban en analizar los paquetes cifrados y no destrozaban las comunicaciones como lo hacían con el puerto en claro.

Tras las charlas, volvimos al salón de actos y votamos con nuestra ficha de póquer a la que pensamos que fue la mejor charla del evento. Ganó la de «Push & Pull» merecidamente, aunque personalmente voté a la charla de CoffeeScript. Y tras una foto de grupo, de vuelta a Cádiz: ya estábamos cansados y había mucho que hacer, así que no pudimos asistir a la fiesta tras el evento.

El Barcamp de este año me ha gustado mucho, he aprendido muchísimo y he tenido oportunidad de encontrarme y reencontrarme con mucha gente interesante (¡hola Moisés!). Si tuviera que poner una pega, diría que fue la calidad de la aplicación Android: la lista de ponencias muchas veces salía vacía a menos que se actualizara mediante un botón Actualizar sólo accesible con la tecla menú (que no aparecía en mi Nexus 7), y en otros casos era imposible deslizar la lista a la derecha para ver las otras «tracks».

Pero vamos, en resumen: que si el Barcamp vuelve el 2013 cerca de Cádiz o en Madrid, contad conmigo :-).

Written by bluezio

23 de septiembre de 2012 at 15:54

Publicado en Desarrollo, Eventos

Apuntes sobre Ice Cream Sandwich en Samsung Galaxy S i9000

with 26 comments

El jueves y el viernes pasé alrededor de 8 horas peleándome por teléfono (por fijo y con tarifa plana :-D) para meter Ice Cream Sandwich (Android 4.0) en el Galaxy S i9000 de un familiar. Gran parte de esas 8 horas fueron más a resolver meteduras de pata mías que a realizar el proceso final (que no llevó más de 1 hora), así que he pensado dejar una guía aquí con unas instrucciones básicas y algunas observaciones.

Un poco de contexto: el Galaxy S i9000 vino inicialmente con Éclair (2.1) y después se actualizó a Froyo (2.2) y Gingerbread (2.3). Por desgracia, Samsung decidió no actualizarlo oficialmente a 4.0, ya que no disponía de la RAM suficiente para ejecutar TouchWiz (la interfaz propia de Samsung) además de ICS. Si queréis ICS, vuestra única opción es una ROM casera, y muy probablemente sin TouchWiz (ni Kies). Así que toca ensuciarse las manos un poco.

Antes de empezar

Os aviso de un par de cosas:

  • Todo esto es a vuestra cuenta y riesgo: aunque tengáis mucho cuidado, siempre existe la remota posibilidad que paséis a tener un bonito pisapapeles, o el equivalente de un iPod Touch. Ninguna de las dos cosas *deberían* ocurrir, pero no me hago responsable :-).
  • Perderéis la garantía en el primer paso de la guía: si aún estáis metidos en una permanencia y no os sentís aventureros, pensadlo dos veces :-).
  • De nuevo: perderéis la interfaz TouchWiz y todos los retoques que ello conlleva, como Kies. Personalmente, no me gustó nunca Kies, pero pensad si necesitáis algo de ahí.
  • Seguid esta guía con la batería al 100%, y a ser posible con el móvil enchufado al cargador o al ordenador. Si se corta la energía y se queda el teléfono a medias, podríais acabar con un pisapapeles igualmente :-).
  • Es posible que perdáis todo lo que haya en la tarjeta SD interna y/o la externa. Haced copia de seguridad de ambas antes de seguir la guía.
  • Las ROM caseras son actualmente bastante estables y tienen mejor rendimiento y más funcionalidades que las ROM oficiales, pero pueden tener pegas. Si queréis curiosear, en el foro de XDA hay a puñados.
  • Esta guía está pensada para una instalación reciente de Ubuntu Linux. Si usáis Windows, tendréis que adaptar algunas de las instrucciones.
  • Está guía está pensada para un Galaxy S i9000 que ya tiene la versión estándar de Gingerbread. Podéis comprobar qué versión tenéis en Ajustes > Estado del teléfono. Debería empezar por 2.3 para que fuera Gingerbread. Si aún tenéis las versiones estándar de Eclair o Froyo, actualizad normalmente mediante Kies a Gingerbread antes de seguir. Si actualizáis por Kies creo que no os quedáis sin garantía, así que estad tranquilos. Si tenéis alguna otra ROM, supongo que no os hará falta esta guía, pero por si acaso volved a un Gingerbread estándar. Más abajo dejo una guía, por si acaso.
  • No me cabe absolutamente todo aquí: recordad que para muchas dudas y demás el foro «Android Development» para i9000 de XDA es muy, muy útil.

No todo va a ser malo: Ice Cream Sandwich trae muchas mejoras, y hay aplicaciones (como Google Chrome) que sólo están disponibles a partir de esta versión. Además, la ROM casera que instalaremos (ICS333) tiene unas cuantas características adicionales. Traduzco algunas de las cosas:

  • Directamente compilado del código oficial de Google (versión IMM76L)
  • Botones mejorados de notificaciones: la pulsación larga en un botón te envía a su menú de Ajustes, y el botón de sonido tiene varios estados
  • Indicador de porcentaje de batería (Opcional – puede cambiarse al original en Ajustes > Batería  > (botón Menú) > Change battery style).
  • Control de brillo en barras de estado y notificaciones (Opcional – puede desactivarse en Ajustes > Pantalla > Brightness control slider).
  • Mejor autobrillo: el brillo realmente baja con menos luz (puede desactivarse en Ajustes > Pantalla > Reducción automática). Basado en el enfoque de stratosk pero usando una escala logarítmica, más ajustada al ojo humano.
  • Menú mejorado de apagado con opciones de reinicio normal, a recovery y toma de pantalla.
  • Salida de TV (ve a Ajustes > Pantalla para activarlo).
  • Efectos de vídeo para caras
  • Matar la aplicación actual mediante pulsación larga en botón Atrás (opcional – puede desactivarse en Ajustes > Opciones de desarrollo > Fast application killing).
  • Elección de almacenamiento en la aplicación de Cámara
  • Botón de encendido como disparador en la Cámara
  • Temporizador en la cámara
  • Marcador T9
  • Los ajustes de Galaxy S de CyanogenMod 9 (otra ROM Android) están todos en el menú de Ajustes
  • Retirado indicador «R» de roaming para roaming nacional (típico en Simyo)
  • Root, Busybox and SuperSU
  • Kernel Semaphore 1.2.2s (387 MB RAM libres para ejecutar vuestras aplicaciones)
  • Cambiado el fichero hosts para quitar anuncios en algunas aplicaciones (fuente: http://winhelp2002.mvps.org/hosts.txt)

El kernel que trae tampoco es el estándar (es Semaphore ICS 1.2.2):

  • Permite controlar los voltajes y frecuencias de la CPU.
  • Permite usar la versión gratuita de Voodoo Sound para mejorar notablemente el sonido de los altavoces y los cascos al escuchar música (mi Nexus S también lo lleva, y creo que es el mejor aparato para escuchar con cascos que ahora mismo tengo). Digamos que la circuitería interna de sonido del i9000 es de alta calidad, pero Samsung no le saca todo el partido.
  • BLN: las notificaciones pendientes encienden los botones capacitivos. Muy útil para ver si te han enviado algo sin encender la pantalla.
  • Deep Idle: si se activa desde las opciones, puede ahorrar mucha batería mientras el móvil está en espera.
  • USB OTG (con ciertos matices).
  • Gobernadores de CPU y planificadores de entrada/salida mejorados.
  • Soporte de carga rápida por USB mediante Fastcharge Widget (útil si el móvil cree que nuestro cargador es un PC – le pasa a muchos cargadores de coche).

Si estáis decididos a arriesgaros a cambio de algo de helado en vuestro i9000, comencemos el proceso :-).

Conceptos básicos

Lo primero es que conozcáis un par de conceptos de bajo nivel del i9000. Tenéis que saber entrar en el «recovery mode» y en el «download mode», que son dos modos especiales de funcionamiento para mantenimiento.

«Recovery mode» (modo de recuperación)

Este modo os abrirá un menú de mantenimiento donde podréis realizar copias de seguridad, instalar una ROM distinta, limpiar el teléfono o reformatearlo, entre otras cosas. El recovery de serie de Samsung no es muy potente: de hecho, en esta guía tendremos que cambiarlo por otro, llamado ClockworkMod.

Para entrar en este modo, primero debéis apagar el teléfono por completo. A continuación, mantened pulsado el botón de volumen hacia arriba, el botón «home» central, y el botón de encendido, en ese orden. Cuando se encienda la pantalla, soltad el botón de encendido.

Para salir de este modo, basta con usar las opciones «reboot system now» o «power off» del menú del recovery. Normalmente os movéis por el recovery con los botones de volumen, y seleccionáis las opciones con el botón de encendido.

«Download mode» (modo de descarga)

Es un modo propio de los Galaxy S y otros aparatos de Samsung para mantenimiento de *muy* bajo nivel. La única forma de comunicarse con el teléfono es mediante Kies, Odin (una herramienta interna de Samsung filtrada al público, *MUY INESTABLE*, y requiere Kies) o Heimdall (una reimplementación de código abierto y mucho más estable de Odin). Esto permite reparticionar la memoria interna y hacer cosas mucho más avanzadas.

En particular, usaremos Heimdall 1.3.1, ya que la 1.3.2 parece tener algunos problemas con los Galaxy S. Instalaos los paquetes Debian de la versión 1.3.1 que vienen en el enlace anterior para vuestra arquitectura (x86 para 32 bits o AMD64 para 64 bits). Podéis saber cuál ejecutando «arch» en una terminal: si sale x86 vuestro sistema es de 32 bits, y si sabe x86_64 es de 64 bits (AMD64).

Para entrar en este modo, las instrucciones son casi las mismas del «recovery mode», pero en este caso es el botón de volumen hacia abajo, el «home» y el botón de encendido. Para salir, mantened pulsado el botón de apagado o quitad la batería (*NUNCA* si Heimdall está haciendo algo en ese momento), o dejad que Heimdall reinicie el teléfono automáticamente cuando termine lo suyo.

Cosas del diseño interno de los Galaxy S a tener en cuenta

Tengo una buena noticia, y una mala:

  • La buena es que es muy difícil dejar el teléfono inservible  siempre que el «download mode» funcione. Si la batería está al 100%, no desconectáis los cables USB mientras opera Heimdall (Odin se desayuna un teléfono y dos gatitos al día, así que olvidaos de él) y no hacéis cosas muy raras, el «download mode» debería funcionar siempre.
  • La mala es que en muchos teléfonos Samsung el IMEI y las MAC de WiFi/Bluetooth (entre otras cosas importantes) vienen en una partición especial llamada /efs. Esta partición es única de cada teléfono y los únicos capaces de regenerarla son los técnicos de Samsung. Si vais a meter ROM y trastear con el aparato, es absolutamente indispensable hacer una copia de seguridad (o dos, o tres) de esta partición antes de nada, y guardarla a muy buen recaudo (en mi caso, Dropbox + Gmail + copia local). Si se corrompe /efs y no tenéis una copia de seguridad, pasaréis de tener un teléfono a tener el equivalente de un iPod Touch :-).

Por ello, el primer paso que seguiremos es hacer una copia de seguridad de vuestra partición /efs (basándonos en este proceso). Sin embargo, para poder hacerla tenemos que obtener acceso de superusuario («root») al teléfono, ya que normalmente no se puede acceder a ella.

«Rootear» el teléfono

Para «rootear» el teléfono hay que instalar un kernel nuevo. ¿Qué es el kernel? Es el sistema operativo del teléfono (una versión especial de Linux), que controla todo el acceso al hardware y funciones de bajo nivel. Tenemos que instalar un kernel alternativo al oficial que nos dé acceso a más cosas.

En particular, descargaremos Semaphore 2.7.4, un kernel con root y otras muchas cosas buenas para Gingerbread (no lo confundáis con el otro Semaphore que es para ICS). Descargadlo de aquí y descomprimidlo a un directorio cualquiera. Deberíais obtener un único fichero llamado zImage. Suponiendo que lo dejamos en /home/yo/semaphore/zImage, ahora apagad el teléfono, ponedlo en «download mode», conectadlo a vuestro ordenador y ejecutad la siguiente orden bajo una terminal:

sudo heimdall flash --kernel /home/yo/semaphore/zImage

Os pedirá la contraseña de vuestro usuario. Una vez la introduzcáis, Heimdall se pondrá manos a la obra y cuando termine, os reiniciará el teléfono. Si todo ha ido bien, el teléfono arrancará de forma normal. De lo contrario, tendréis que volver a reinstalar el Gingerbread de vuestro teléfono (algunos apuntes debajo).

Una nota: de 3 usuarios que sé que han seguido esta guía, 2 han usado Semaphore 2.7.4 sin problemas y uno ha tenido que usar CF-Root, el kernel en que está basado a su vez Semaphore. Si al «rootear» con Semaphore tenéis problemas, deberíais probar con CF-Root.

Copias de seguridad de /efs

Una nota: a los usuarios de Windows les podría venir bien esta aplicación para automatizar el proceso.

Con el nuevo kernel instalado, seguiremos una variante de este proceso para hacer dos copias de seguridad de /efs: sacaremos una copia del directorio /efs en sí, y una imagen de la partición /efs. Nunca viene mal hacerla de varias formas, por si acaso :-). El primer paso es instalar adb, la herramienta para acceder a las funciones de depuración de Android (el «Android Debug Bridge»). Para instalarla, descargad la última versión del Android SDK para Linux de aquí y descomprimidla a un directorio. Entrad en el subdirectorio tools y ejecutad «./android». Se os abrirá un gestor de paquetes: marcad las «Platform Tools» y nada más, e iniciad la instalación. Cuando termine, «adb» debería aparecer mágicamente dentro de «platform-tools» en el directorio principal del SDK.

Desde una terminal, id a ese directorio platform-tools y ejecutad esta orden, teniendo el teléfono conectado al ordenador:

./adb devices

Si os sale una salida de este tipo, ADB se puede comunicar bien con vuestro dispositivo:

(identificador con letras y números)     ("device" o algún nombre de aparato)

De lo contrario, tendréis que revisar si las funciones de depuración están activadas en vuestro teléfono (mirad en «Ajustes > Aplicaciones»), y si existen las reglas udev oportunas.

Una vez ADB pueda hablarse con vuestro aparato, podremos seguir. Desde esa terminal, ejecutad esta orden para abrir una terminal dentro del propio teléfono:

./adb shell

Veréis que la terminal cambia a algo del tipo:

blablabla $

El «$» al final indica que sois usuarios normales, así que vamos a pedirle que nos suba a superusuarios:

su

Si es la primera vez que usamos «su», el teléfono nos preguntará si queremos darle acceso de superusuario a la terminal. Le diremos que sí (y yo normalmente le digo que lo permita para siempre). Ahora la terminal debería estar como:

blablabla #

La «#» final indica que somos superusuarios. Atención a las órdenes que mandéis ahora que tenéis todo el poder: puede usarse para el bien, o para el mal :-). Bueno, pues sigamos:

busybox tar czvf /sdcard/efs.tar.gz /efs

Esta orden os creará un fichero llamado efs.tar.gz en vuestra tarjeta SD interna, que contiene una copia de seguridad comprimida de la partición /efs. Por si acaso, también sacaremos una imagen de la partición, pero primero tenemos que conocer su ruta de bajo nivel. Para ello, primero miraremos con:

mount | grep /efs

Debería aparecer una sola línea, con una ruta de la forma «/dev/…». Apuntad esta ruta, y ejecutad:

dd if=/dev/... of=/sdcard/efs.rfs

Si todo va bien, ahora en la tarjeta SD interna tendréis una imagen de esa partición (normalmente ocupa unos 6MB). Para sacar esos ficheros, salid de ADB mediante:

exit
exit

El primer «exit» os sacará del modo superusuario, y el segundo os sacará del terminal de ADB. Ahora que estamos de vuelva en la terminal normal, vamos a sacar esos ficheros de la tarjeta SD interna mediante:

./adb pull /sdcard/efs.tar.gz ~/efs.tar.gz
./adb pull /sdcard/efs.rfs ~/efs.rfs

Las copias de seguridad estarán directamente bajo vuestro directorio personal. Ponedlas a buen recaudo, que nunca sabéis cuándo os harán falta :-).

Instalación de ICS333

Ahora vamos a dar el paso grande. Antes de eso, comprobad estas cosas:

  • Deberíais estar corriendo Gingerbread estándar en vuestro Galaxy S i9000.
  • Deberíais tener acceso root a vuestro teléfono y el recovery de ClockworkMod (el kernel que pusimos antes lo instaló de paso).
  • Deberíais tener una copia de seguridad de vuestra partición /efs, guardada a muy buen recaudo. Vuestro ordenador no es «buen recaudo»: deberíais tener por lo menos una copia en algún soporte externo y otra en algún servicio online, que después fallan los discos duros y toca llorar :-P.
  • Deberíais tener una copia de seguridad de vuestras aplicaciones, SMS y demás. Para ello, Titanium Backup es ideal (exige permisos de superusuario, pero si habéis seguido esta guía ya los tenéis). Y compraos la versión Pro: los mejores 4,99€ que os habréis gastado en mucho tiempo si os gusta trastear ;-).
  • Tras hacer la copia de seguridad de Titanium Backup, deberíais hacer copia de seguridad de las tarjetas SD interna y externa a otra máquina: vuestro ordenador, por ejemplo.

¿Todo hecho? Pues vamos a seguir una adaptación de esta guía.

Descargad este fichero (es la ROM en sí) y este otro (son las aplicaciones de Google: por cuestiones legales no se pueden integrar en la ROM), y meted ambos en la tarjeta SD externa del teléfono. Podríais usar el almacenamiento USB de toda la vida, o emplear adb de nuevo:

./adb push (ruta a ICS333-2.0.1-signed.zip) /mnt/sdcard/
./adb push (ruta a gapps-ics-20120429-signed.zip)  /mnt/sdcard/

Ahora apagad el teléfono, y reiniciadlo en modo recovery con las instrucciones de arriba. Ejecutad las órdenes «Wipe data/factory reset» y «Wipe cache»,  y seleccionad «install zip from sdcard > choose zip from sdcard». Seleccionad ICS333-2.0.1-signed.zip y confirmad que queréis aplicar sus cambios. Cuando lleve un poco, se os reiniciará el teléfono debido a que el kernel ha cambiado, y se quedará parado en el logotipo de Semaphore. Esperad un poco, y si veis que no responde (es normal) apagadlo manteniendo pulsado el botón de apagado, o a unas malas quitando la batería. Encendedlo de nuevo en modo recovery y aplicad de nuevo ICS333-2.0.1-signed.zip: esta vez llegará al final, y os devolverá al menú principal.

Volved a «choose zip from sdcard», pero esta vez aplicad gapps-ics-20120429-signed.zip. Por si acaso, haced otro «Wipe data/factory reset» y «Wipe cache» de nuevo, y reiniciad el sistema mediante «reboot system now».

Una vez se reinicie el sistema, ya podréis disfrutar de Ice Cream Sandwich. ¡Que aproveche!

Posibles problemas

El sistema arranca bien, pero no tengo servicio en el teléfono, y/o no tengo IMEI

Es hora de aprovechar esa copia de seguridad que hicisteis de /efs, porque ¿la hicisteis, verdad? De lo contrario, llevadlo al SAT de Samsung: nadie más lo va a poder reparar.

Coged el efs.tar.gz que generamos en su momento y extraed el nv_data.bin de ahí. No necesitamos nada más, en principio. Colocadlo en vuestra tarjeta externa, y con el móvil encendido en el sistema normal y conectado al ordenador, id al directorio platform-tools (donde está «adb») y ejecutad:

./adb shell
su
cp /emmc/nv_data.bin /efs/nv_data.bin
busybox rm - f /efs/nv_data.bin.md5
chown radio /efs/nv_data.bin
chgrp radio /efs/nv_data.bin
chmod 644 /efs/nv_data.bin
reboot

Ahora se os reiniciará el teléfono, y ya deberíais tener servicio de teléfono. Si aún no, tendréis que probar otras guías para recuperar el servicio a partir del /efs, o volver a un estado consistente mediante las instrucciones de la siguiente sección.

El sistema no arranca, pero el «download mode» sí

En este caso, probad a hacer un wipe y reinstalar la ROM y gapps. Si eso no sirve, puede que el teléfono haya quedado en un estado inconsistente que le impida arrancar bien. Vamos a limpiar el teléfono completamente (tarjeta SD interna incluida) para dejarlo justo como sale de fábrica, con Gingerbread 2.3.6.

Para ello, en este hilo hay una imagen limpia preempaquetada para Heimdall: en particular, queremos la XXJVU (enlace). Descargad el fichero a vuestro ordenador y no lo descomprimáis.

Ahora encended el teléfono en «download mode» y conectadlo al ordenador. En una terminal, ejecutad la siguiente orden:

sudo heimdall-frontend

Se os abrirá una ventana con el interfaz gráfica de Heimdall, la herramienta que antes usamos para «rootear» el teléfono. Bajo la pestaña «Load Package», pulsad «Browse» y seleccionad el fichero XXJVU_Heimdall.tar.gz que antes descargasteis. Heimdall descomprimirá el fichero y hará una serie de comprobaciones. Cuando termine, veréis que indica que la ROM sólo es usable con i9000, y os listará unas cuantas entradas en «Package Files». Pulsad en «Load / Customise», y os pasará a «Flash».

Bajo la pestaña «Flash», pulsad en «Add» y aseguraos de que en Partition diga «EFS». Pulsad en Browse y seleccionad el fichero efs.rfs que antes creamos. Ahora pulsad en Start, y dejad que Heimdall haga lo suyo. El teléfono se reiniciará automáticamente, y tendréis vuestro Galaxy S de vuelta en Gingerbread funcionando normalmente. Es posible que no sea exactamente el de vuestra operadora, pero por lo general funcionará bien y os dará servicio. Sois libres de reintentar las instrucciones de esta guía llegados a este punto. Si queréis, podríais probar otra ROM ;-). Me han comentado por Facebook que las versiones recientes de CyanogenMod 9 van bastante bien.

El sistema no arranca, y tampoco el «download mode»

Lamento decir que en este caso, sólo queda llevarlo al SAT de Samsung. La única forma de acceder al dispositivo será mediante unos puntos de contacto en la propia placa base del aparato en este caso, y los únicos que tienen ese tipo de equipamiento y el software correspondiente son los técnicos de Samsung, me temo.

Written by bluezio

14 de julio de 2012 at 16:57

Publicado en Android

Tagged with , , , , , ,

Despiece de Sony Ericsson MW600 y cuestiones de sostenibilidad

with 29 comments

La semana pasada mi querido manos libres estéreo Bluetooth Sony Ericsson MW600 dejó de encenderse de repente. Originalmente pensaba que sería su mal hábito de quedarse «colgado», y seguí las recomendaciones habituales de dejar que se descargara a lo largo de varios días, para que se apagara completamente y volviera a responder tras volverlo a cargar.

Sin embargo, en este caso no sirvió de nada en absoluto. De hecho, el problema es que no encendía. A veces, al conectar el MW600 a un cargador mostraba un indicador de batería lleno, y justo tras desconectar y volver a conectarlo mostraba la animación. Este comportamiento tan raro me hizo sospechar de la batería, así que consulté con el servicio técnico y me dijeron que no había otra opción que llevarlo a reparar. El problema es que el aparato estaba fuera de garantía: lo compré en noviembre de 2010, así que ya habían pasado más de los 12 meses que tenía (lo compré en Amazon UK). Me podría salir el arreglo más caro que un MW600 nuevo :-/.

Por ello, mi siguiente paso fue intentar desmontar el bicho a mano y mirar si podía reemplazar la batería por mi cuenta. Aunque no he podido localizar un proveedor minorista de una batería compatible, me ha servido para aprender un poco cómo está hecho un bicho de éstos. Ayer estuve mirando cascos estéreo Bluetooth por todos lados, y por mucho que me pese el MW600 sigue teniendo la mejor relación calidad/precio, así que he pedido otro MW600 de Amazon España por 26€. En Play.com estaba a 20€, pero al ser de UK la garantía volvía a ser de 1 año, en vez de los 2 años que tenemos por ley en España.

Tras decidir reemplazar el aparato, he repetido el desmontaje, esta vez con un propósito más ingenieril y hasta el final :-D. Dejo por aquí los pasos por si alguien tiene curiosidad. Notaréis que mi unidad está algo dañada: eso es por el primer desmontaje, que fue algo manazas :-).

Aquí tenéis el sujeto de pruebas, por el lado del control capacitivo de volumen:

Hay mucha gente que se queja de este control capacitivo y preferiría una rueda tradicional, pero personalmente creo que este diseño es más resistente mecánicamente (no hay partes móviles) y aguanta mejor el polvo y humedad. También se puede ver la pinza, que de hecho es uno de los puntos débiles del MW600: uno de mis familiares rompió la suya sin querer tras engancharse con un mueble. Es plástico normal y corriente, al fin y al cabo.

El primer paso para desmontar este trasto es quitar la pinza, precisamente. La forma más fácil es coger un palito largo y fino (o la punta de un destornillador de estrella) y presionar sobre uno de los pivotes que encajan la pinza al resto del cuerpo del aparato. Os lo marco en rojo aquí:

Sacada la pinza, nos quedará así:

Como puede verse, la pinza del MW600 no es mucho mejor que un alfiler para tender la ropa: un simple muelle da su «fuerza», y la unión entre el muelle, el cuerpo y la pinza en sí es puramente mecánica, con un eje de plástico. De todos modos, algo más fuerte pesaría y ocuparía más.

El siguiente paso es retirar los botones de goma que permiten pausar canciones y llamadas y saltar entre canciones. Los podéis ver aquí:

Si os fijáis bien, los controles de la música tienen un pequeño «marco» de plástico alrededor. Este marco es lo que fija los botones al cuerpo principal del aparato. Para retirarlo, basta con introducir un objeto fino en el hueco (que sea blando, o si no puede que deforméis el marco sin querer, como yo :-P) y hacer palanca. El marco tiene una serie de clips de sujeción que se retiran haciendo presión. Os quedará así:

Bueno, casi: si lo habéis hecho bien, aún tendréis los tres botones del aparato :-). En mi primer desmontaje no retiré estos botones antes de los pasos siguientes y el botón izquierdo saltó. Como veis, están simplemente pegados: son botones de membrana, y no interruptores «de verdad» (más resistentes, pero más grandes, pesados y costosos). Los botones de goma son simplemente una forma cómoda de pulsar esos botones pequeños.

Con los botones retirados, ya podemos quitar el protector de plástico que cubre el extremo con el conector MicroUSB. Para ello, antes hay que despegar con una uña o un objeto blando y fino el embellecedor que oculta el tornillo:

Tras retirar el tornillo (¡cuidado con perderlo!) podemos sacar el protector y la cubierta de goma del botón de encendido (está simplemente encajada):

De nuevo, el botón «de verdad» es pequeñísimo. En este caso sí que es un interruptor normal. Después comentaré una cosa interesante del puerto MicroUSB, pero por ahora retiraremos el tubo de plástico que cubre la parte central de la unidad, simplemente sacándolo por el extremo del MicroUSB (está simplemente encajado):

Como veis, el tubo de plástico es de una sola pieza, y el botón de llamada (encajado y punto) oculta otro interruptor pequeño que sale directamente de la placa del MW600. Si le damos la vuelta al cuerpo del aparato, podemos acceder a la batería:

Aquí tenemos la batería del MW600. Retirarla exige algo de esfuerzo, ya que está pegada (sí, pegada) al fondo del compartimento, pero con un poco de cuidado sale:

Como veis, es una GP0836L17 de 0.6Wh. Buscando un poco, parece ser fabricada por GP Batteries (datasheet). Mide 8.2mm (diámetro) x 35.5mm (largo) y es una batería cilíndrica de ión litio de 170mAh a 3.7V. Se puede ver que es de ión-litio tras retirar la pegatina negra que cubre la mitad superior para que no se vea el blanco de la batería a través del tubo de plástico:

El problema es que GP Batteries es una mayorista y no vende a particulares. En Amazon.com parecen vender una compatible con MW600 y con sus modelos anteriores MH100 y MH600, aunque es de ión-polímero y el vendedor no envía a España. Además, por $15 + envío + aduanas sale más económico comprar un MW600 nuevo. Por cierto, sus dimensiones no se corresponden con ningún estándar, así que olvidaos de buscar una genérica por ahí. Aquí la tenéis al lado de una pila AAA:

Como veis, usar una pila estándar habría añadido un centímetro más de largo y algo más de diámetro. ¿Habría merecido la pena que la batería fuera reemplazable, por sostenibilidad? Es cierto que pesa bastante más, y eso podría causar rechazo a los potenciales compradores. Pero no dejo de pensar que simplemente usar una celda de ión-litio con dimensiones estándar ya habría sido suficiente para poder arreglarlo con destornillador y datasheet en mano. Lo malo de todos estos bichos con baterías imposibles de reemplazar es que son bombas de relojería para el comprador: por muy bien que los trate, eventualmente fallarán. ¿De verdad tenemos que comprar uno nuevo cada 18-24 meses?

Volviendo al tema: ya hemos hecho todo el desmontaje útil, pero ahora vamos a terminar de abrir el cacharro, ya por curiosidad :-). Vamos a retirar el protector del extremo de los cascos, quitando el tornillo que está justo por la parte de la pinza:

El pequeño objeto dorado que vemos de canto es el micrófono de llamadas. Ahora vamos a retirar la cubierta superior del aparato. Cuidado: a partir de aquí todo es básicamente irreversible, ya que está todo pegado y volver a pegarlo justo como estaba va a ser difícil.

Para retirar la cubierta superior, hay que retirar cuatro clips de sujeción (dos en cada lado de cada extremo), y despegar la parte que protege a la pantalla OLED:

Por la parte del micrófono notaréis que he despegado dos pequeñas placas impresas. Son las antenas, como os imaginaréis por el diseño en espiral que tienen dibujadas. Ah, y están pegadas con celofán transparente de dos caras :-D. La pantalla OLED está pegada a la placa. Con un poco de fuerza por el extremo cercano al micrófono, se levanta fácilmente:

La pantalla no se puede separar de la placa, ya que su cable está unido directamente a ella, en vez de conectado a un enchufe como suele ocurrir en los portátiles. El «ribbon cable» usado es ligero y fino, pero como hubiera que cambiar la pantalla… ¿no se podría haber usado un conector normal? Así se podría cambiar la pantalla, aunque podría añadir un par de milímetros al largo del aparato.

En fin, volviendo al tema. La placa madre y la placa hija con el control capacitivo están pegadas al armazón de plástico. Tras despegarlas, ya podemos ver toda la electrónica del MW600:

Como veis, el MW600 está formado por una placa principal con casi toda la circuitería y 4 placas hijas conectadas con «ribbon cables»: la superior tiene los controles capacitivos (4 zonas diferenciadas), la inferior tiene 3 botones de membrana con los controles de música, y las dos pequeñas al lado del micrófono forman la antena del aparato. Se me pasó hacer una foto del otro lado, pero curiosamente el conector USB no está soldado a la placa, sino que hace contacto mediante 3 puntos del otro lado de la placa principal: esto indica que se podría cambiar fácilmente el puerto USB (si no fuera por tanto pegamento). Lo mismo pasa con el compartimento de la batería: las dos pestañas de contacto simplemente tocan dos puntos de la placa. Sin embargo, el conector de los cascos está soldado con estaño. Supongo que esto le dará bastante resistencia mecánica al conector.

Y aquí están todas las piezas del MW600 (os destaco el conector Micro USB):

Tras despiezar el bicho, pienso que no me importaría pagar algo más por un trasto más sostenible: la pantalla podría estar conectada normalmente en vez de pegada a la placa, y se podría sujetar mediante clips de sujeción en vez de tanto pegamento. La batería podría usar pilas recargables normales, o por lo menos celdas de tamaños estándar. Sin embargo, todo esto añadiría peso y coste, evidentemente. Al final es un equilibrio, y ahora mismo está ganando reducir costes de producción y peso, pero es prácticamente imposible hacer ningún tipo de mantenimiento en estas cosas.

Me encanta el MW600, pero si saliera una variante con batería reemplazable ya sería perfecto. Lo malo es que esta obsolescencia programada le viene de perlas a los fabricantes :-/. Por lo menos el MW600 te permite usar tus propios cascos, con lo que se reducen los puntos de fallo, pero la batería sigue siendo un problema. El problema es que prácticamente no existen manos libres con baterías reemplazables: el único que he visto es el Motorola H300, que utiliza una pila AAA estándar, pero es antiquísimo.

Intenté «castigar» a Sony Ericsson comprando un manos libres de otro fabricante, pero por mucho que busqué no encontré mejores alternativas para mi caso. Como salgo a correr todos los días, las alternativas que incorporan los cascos en el propio aparato se estropearían rápidamente por sudor o estrés mecánico (Plantronics Backbeat 903+, Motorola S10 HD, Sennheiser MM100, LG HBS700, Nokia BH505). Necesito sonido estéreo para escuchar música, así que los modelos de una sola oreja no valdrían. Eso me deja de nuevo con los modelos de tipo clip (como el MW600): el Samsung HS3000 (al andar o correr genera ruido), el Samsung HM3700 (interesante, pero imposible de comprar en Europa y sin controles de música), el Samsung HM6450 (igual que el HM3700), el Jabra CLIPPER (conector de cascos delicado) o unos cuantos de Nokia (más limitados y caros que el MW600 desde España).

Lástima: a ver si en un futuro alguien se da cuenta de que este ritmo de tirar y comprar cacharros cada 18-24 meses no es sostenible :-/.

Written by bluezio

8 de julio de 2012 at 19:03

Publicado en Uncategorized

Reutilizar un móvil Android como webcam con DroidCamX e IP Webcam

with 5 comments

A raíz de este artículo de El Androide Libre, me puse a probar DroidCamX e IP Webcam para convertir mi Nexus S (corriendo una ROM basada en Gingerbread 2.3.4) en una webcam HD, posiblemente con micrófono incorporada. He tenido éxito con IP Webcam y he conseguido que funcione tanto en Windows 7 como en Ubuntu Natty, pero me ha llevado su buen rato. Dejo aquí los apuntes para que Google pueda encontrarlos :-D.

En primer lugar probé DroidCam (la versión gratuita de DroidCamX), que tenía buenos análisis. Requiere instalar un cliente para Windows/Linux y una aplicación en el móvil. El cliente para Windows iba bien, pero sin sonido (dejó de funcionar en Gingerbread y exige arrancar Windows 7 de 64 bits desactivando la comprobación de firma de drivers). Lástima. El cliente en mi Ubuntu Natty de 64 bits (basado en Video4Linux2) no funcionó de ninguna de las formas (y sí, probé con la versión de 64 bits). A veces daba errores de «Failed to write frame (bad address)», y en otros casos tanto Cheese como Skype daban bonitas pantallas negras.

De todos modos, pensando en apoyar el desarrollo de este programa y las funcionalidades adicionales, eché los 3 euros y compré DroidCamX. Añade autoenfoque por toque, la posiblidad de cambiar la resolución y el códec para la comunicación PC-móvil y un cliente web integrado. Todo funcionó bien menos el cliente web: el formato de vídeo A no servía para resoluciones decentes, el formato B mostraba artefactos y el formato C tenía un parpadeo muy molesto al verlos por la web. Ah, y DroidCamX tampoco funcionó en Ubuntu de ninguna de las formas. Una pena.

Tras dejar DroidCamX como webcam inalámbrica para Windows, decidí probar IP Webcam. Era gratuita, pero inicialmente la descarté ya que no tenía un cliente nativo para Linux. Permite cambiar la resolución y calidad de imagen, controlar el LED del flash a distancia, grabar sonido y tiene una mejor interfaz web. A diferencia de DroidCam, creo que en vez de codificar vídeo, se dedica únicamente a tomar 15 imágenes JPEG por segundo y reunirlas en un flujo continuo (MJPEG). Eso hace que el vídeo sea algo menos suave que el de DroidCam, y que exija más ancho de banda, pero le permite reutilizar drivers genéricos para Windows que convierten un flujo MJPEG en una webcam local, utilizable por Skype y otros programas similares.

En el lado de Ubuntu requiere algo de trabajo, pero se pueden reutilizar varios programas que ya existen para usar IP Webcam como una webcam local. La idea básica es crear un dispositivo Video4Linux2 virtual que lea el flujo MJPEG y sea visible para Cheese, Skype y demás como una webcam más. Originalmente, para Video4Linux existió vloopback, pero este proyecto se abandonó tras la retirada de V4L1 a favor de V4L2 desde la versión 2.6.15 del kernel de Linux. AVLD es otra herramienta parecida para V4L1, también abandonada. Para V4L2, hay otros dos proyectos: v4l2vd (no compila a partir del kernel 2.6.31) y v4l2loopback (compila en mi 2.6.38). Así que la idea básica es crear un dispositivo virtual con v4l2loopback, y luego enviarle los datos de vídeo necesarios para nuestras aplicaciones. Para ello, podemos usar GStreamer y su componente v4l2sink, por ejemplo. Esto da mucho más juego que una simple webcam: podríamos enviar cualquier vídeo o aplicar cualquier efecto a través de esa «webcam». Pero claro, todo tiene su complicación :-D.

Primero, tenemos que compilar e instalar v4l2loopback, y luego cargar el módulo instalado:

sudo apt-get install git build-essentials linux-source
git clone git://github.com/umlaeute/v4l2loopback.git
cd v4l2loopback
make && sudo make install
sudo modprobe v4l2loopback

Si todo ha ido bien, deberíamos tener un fichero /dev/video* más que antes. Ese será nuestra tubería. Por lo pronto, supongamos que es /dev/video0, el primero de todos. Si queremos que este módulo se cargue automáticamente al iniciar el ordenador, tendremos que añadir estas dos líneas tras la última línea de /etc/modules:

videodev
v4l2loopback

Con el módulo cargado, ya podemos ver si capturamos bien la señal de la webcam. Para ello, iremos a la interfaz web de IP Webcam y cogeremos la URL del flujo MJPEG, que será de la forma http://ip:puerto/videofeed. Con esa dirección, lanzaremos estas órdenes desde una terminal. Si todo ha ido bien, debería salir una ventana con lo que se ve en la pantalla de nuestro Android:

sudo apt-get install gstreamer-0.10-tools
gst-launch souphttpsrc location="http://ip:puerto/videofeed" is_live=true ! \
  jpegdec ! ffmpegcolorspace ! autovideosink

Ahora podemos salir con Ctrl+C de gst-launch, y empezar a reenviar el flujo MJPEG a nuestro dispositivo V4L2 virtual. Tendremos que repetir esto cada vez que reiniciemos el ordenador, por cierto:

gst-launch souphttpsrc location="http://ip:puerto/videofeed" is_live=true ! \
  jpegdec ! ffmpegcolorspace ! v4l2sink device=/dev/video0

Vamos a diseccionar un poco esto:

  • Primero, la fuente souphttpsrc accede a la dirección HTTP especificada y va bajando información en directo, sin ningún búfer (is_live=true).
  • A continuación, jpegdec identifica cada imagen en el flujo MJPEG y las reúne en un vídeo en el espacio de colores YUV.
  • El componente ffmpegcolorspace convierte el vídeo YUV en el formato preferido por el dispositivo V4L2 virtual.
  • Finalmente, el sumidero v4l2sink escribe la información en el dispositivo /dev/video0, para que sea visible por Cheese/Skype/etc.

Ahora deberíais poder abrir Cheese o Skype (2.1.0.81, ojo, que la 2.2 beta ahora no va) y veros por pantalla :-D. Si tenéis curiosidad, añadid un par de filtros, como:

gst-launch souphttpsrc location="http://ip:puerto/videofeed" is_live=true \
  ! jpegdec ! ffmpegcolorspace ! mirror ! videobalance saturation=0.0 \
  ! v4l2sink device=/dev/video0

Para más ideas, mirad los complementos que hay en la web oficial de GStreamer. Hay para todo. Una recomendación: si queréis video suave y sesiones largas, lo mejor es que mantengáis el móvil conectado por USB al ordenador y uséis el reenvío de puertos de ADB para enviar los datos a través de USB, en vez de por Wi-Fi. Para ello, tenéis que instalaros el SDK de Android y ejecutar esta orden:

adb forward tcp:8080 tcp:8080

Con esta orden, todo lo que enviéis al puerto 8080 de vuestro ordenador irá al 8080 del móvil, a través del cable USB. Cuando hagáis eso, será mucho más rápido acceder a IP Camera por http://127.0.0.1:8080/ que con vuestra conexión Wi-Fi.

Actualización (12:28): he conseguido que funcione el micrófono en Linux también. El esquema es un poco enrevesado: el flujo WAV de la webcam va a un sumidero nulo de PulseAudio, y la fuente asociada al monitor del sumidero nulo se usa como dispositivo de grabación de la aplicación de videoconferencia. Funciona bien, pero olvidaos de conectar por Wi-Fi :-D. Además, he creado un guión para facilitar el uso de la cámara y el micrófono, aunque tendréis que instalar el SDK de Android y v4l2loopback a mano de todos modos. Lo he colgado por Github, por si alguien lo quiere.

Actualización (domingo 10 julio): tras hablar con el desarrollador, parece que añadirá un enlace al guión en Github en la próxima versión. Gracias a sus sugerencias, el guión ahora instala v4l2loopback por DKMS e inicia IP Webcam automáticamente si el móvil está conectado por USB y ADB está disponible. Definivamente, ha quedado mucho mejor :-D.

Written by bluezio

8 de julio de 2011 at 8:30

Eclipse Commiter en Epsilon

leave a comment »

Me alegra decir que acabo de entrar como Committer en el proyecto Epsilon de Eclipse GMT. La verdad es que llevaba desde verano del 2009 contribuyendo pequeños cambios para cubrir fallos que me encontraba y necesidades que tenía.

Ahora estoy de estancia en la University of York con los desarrolladores de Epsilon (Dimitris Kolovos y Louis Rose), realizando una contribución más grande, y decidieron invitarme al proyecto. La verdad es que está siendo muy interesante y están saliendo cosas curiosas. Estoy ocupado desarrollando EUnit, un marco de pruebas unitarias para temas de modelos, basado en Epsilon. Tengo en la cola de prioridades un artículo acerca de él: cuando tenga algo más definido, hablaré un poco más de EUnit por aquí.

Por lo pronto tengo 50 commits que limpiar y subir al SVN de Eclipse :-D. Por supuesto, estoy usando git-svn: es una alegría ver que puedes replantear tus 50 últimos commits limpiamente sobre los últimos cambios de Dimitris y Louis en SVN.

Written by bluezio

18 de abril de 2011 at 15:09

Publicado en Desarrollo

Tagged with , , , ,

Smart HTTP de Git y Redmine

with 5 comments

Actualmente estoy preparando la actualización de un servidor Redmine que gestiono. Es una actualización bastante grande: no es sólo cuestión de actualizar la instancia Redmine, sino todo el sistema y herramientas de apoyo. Lleva demasiado tiempo sin tocarse y tiene una distribución antigüilla.

Una de las cosas que quería añadir en el servidor actualizado (junto con Redmine 0.9.2, la última versión estable a fecha de hoy) era soporte integrado con Git. Sin embargo, hay un problema, conocido por todos los usuarios de la red de la Universidad de Cádiz: el cortafuegos cierra el paso a prácticamente todo salvo correo y HTTP (y ocasionalmente HTTPS). Por eso, muchos de los protocolos que admite Git están fuera de la cuestión: el propio de Git (que de todos modos no serviría para los push), SSH (como lo proponga le da un patatús al CITI) y rsync (en desuso).

Git ha permitido el uso de HTTP y HTTPS desde hace tiempo sobre WebDAV, al estilo de Subversion, pero nunca me ha gustado este método. Además de sus problemas de rendimiento, de no poder usar «hooks» (manejadores de eventos) y de las molestias que origina (hay que meter un trabajo cron que ejecute «git update-server-info» periódicamente en cada repositorio), tiene una pega gravísima: la consistencia del repositorio está a completa merced de todos y cada uno de los clientes que acceden al repositorio.

Cuando di mi primer curso de Git en 2008, algunos de los asistentes me dijeron tajantemente que ni hablar de activar SSH en sus máquinas, así que probamos el acceso por HTTP. Curiosamente, el primer día que lo probamos y estuvimos mandando commits en rápida sucesión, se corrompió el repositorio varias veces. Al siguiente día, no se corrompió en absoluto, y le estábamos mandando cosas incluso más rápido que antes. Pero entonces llegó uno de los asistentes que faltaba, y dicho y hecho: a los pocos minutos estaba corrompido. El origen del problema: la versión de Curl del asistente que había venido (único usuario de MacBook en la sala, jeje) era antigua. Cuando Git trabaja sobre WebDAV, el servidor HTTP sirve de poco más que de un área de subida de ficheros. Si la versión de la biblioteca curl instalada en el cliente tiene fallos, éstos repercutirán en el repositorio (como con Curl 7.16.0). Ah, y por supuesto no hay nada de atomicidad: si el usuario pulsa Ctrl+C en mitad de la actualización o se le va la conexión, puede que el repositorio también se quede en un estado inconsistente.

Por estas razones, descarté incluso HTTP/HTTPS, y no metí Git en la instalación actual de Neptuno. Todo se quedó en una instalación de Gitosis en mi servidor doméstico. Sin embargo, Git 1.6.6 incluye «smart HTTP«, que arregla los problemas de rendimiento, llama a los «hooks», evita la necesidad del trabajo cron con «git update-server-info» y proporciona las mismas garantías de atomicidad que el acceso por SSH. El «truco» es que ya el servidor HTTP no es una tonta área de almacenamiento WebDAV, sino un CGI que implementa los servicios que usualmente se invocan mediante SSH a través de HTTP. Lo bueno de todo esto es que además, al ser HTTP, podría integrarlo directamente con el esquema de autenticación de Redmine, con lo que un proyecto público admitiría fetch anónimo pero limitaría los push a los miembros con derecho a commit, y un proyecto privado exigiría los derechos apropiados para tanto fetch como push. La única «pega» es que hay que tener Git 1.6.6 como mínimo tanto en el cliente como en el servidor, pero bueno, los verdaderos usuarios de Git se lo compilan desde las fuentes, que no es tan difícil ;-).

Sin embargo, esta configuración de Apache que combina las instrucciones del CGI con una variación de la propuesta en la web de Redmine no sirve directamente:

SetEnv GIT_PROJECT_ROOT /var/www/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
PerlLoadModule Apache::Authn::Redmine
<Location /git>
  Order deny,allow
  Allow from all

  PerlAccessHandler Apache::Authn::Redmine::access_handler
  PerlAuthenHandler Apache::Authn::Redmine::authen_handler
  AuthType Basic
  AuthName "Redmine Git Repository"
  Require valid-user

  RedmineDSN "DBI:mysql:database=databasename;host=my.db.server"
  RedmineDbUser "usuario"
  RedmineDbPassword "contraseña"
</Location>

Cuando lo probé, no podía crear clones de forma anónima de un proyecto público: tenía siempre que introducir contraseña. Además, tampoco podía hacer push en un proyecto público, por mucho que pusiera la contraseña. La explicación es algo larga, pero es interesante (y me llevó unos buenos tirones de pelos y media mañana :-/). Está dividida en dos partes:

  • El hecho de que fallaran los clones anónimos es que el manejador de autenticación de Redmine, pensado para WebDAV como está, distingue las acciones de «sólo lectura» (las que pueden hacerse de forma anónima en proyectos públicos y que no requieren derechos de escritura para los miembros de proyectos privados) del resto a través de sus métodos HTTP. Por omisión, estos métodos son GET, PROPFIND, OPTIONS y REPORT: por definición, no deberían producir cambios en los recursos a los que acceden. Sin embargo, al hacer «fetch» con smart HTTP de Git se hace una petición POST al servicio git-upload-pack, y hace que pida contraseña: nos quedamos sin fetch anónimo.
  • El segundo problema se debe a que git-http-backend, el CGI necesario en el servidor para «smart HTTP», obliga por omisión a que todos los push (peticiones al servicio git-receive-pack)  tengan algún tipo de autenticación. De lo contrario, los rechaza con un código de error 403 (Forbidden). Y aquí volvemos con el problema de distinguir las acciones por los métodos HTTP: el servicio git-receive-pack se utiliza en dos fases. La primera fase es un GET a /git/repositorio/info/refs?service=git-receive-pack: git-http-backend exige autenticación, pero el manejador de Redmine no se la pide al usuario, ya que es un método de sólo lectura. Resultado: un bonito Forbidden (403) para cualquiera que quiera hacer push. Los tirones de pelos en este lado vienen de que Git, al ver que el push por smart HTTP no ha ido, asume que el servidor es de tipo WebDAV, y hace más peticiones que hacen más difícil encontrar el problema. Actualización 14/03/2010: puede que en dentro de poco se deje de pedir contraseña para el GET.

¿Cómo corregir esto? Pues haciendo que el manejador de Redmine distinga las peticiones «de sólo lectura» del resto no por método HTTP, sino por dirección, tal y como viene en la página man del CGI (segundo ejemplo de configuración de Apache). Podría haber desarrollado un nuevo manejador de autenticación, pero duplicaría todo el código salvo en un par de sitios. He preferido añadir una nueva directiva que activa este comportamiento, que por omisión está deshabilitado: RedmineGitSmartHttp. Para usarla, pondríamos esta línea dentro del anterior <Location /git>:

RedmineGitSmartHttp yes

y ya todo debería ir sin problemas. Esto no afectará a los bloques <Location /svn> que tengamos en otra parte: se usan instancias distintas del manejador de autenticación, y esas instancias no tendrán esta opción activada, por lo que mantendrán el antiguo comportamiento. Bueno, por lo menos así me ha funcionado en mi servidor de pruebas y así lo indican sus registros :-D. He probado con proyectos públicos y no públicos en SVN y Git en el mismo Redmine y ha ido bien.

Para aquellos interesados en el código, he enviado un parche al proyecto Redmine, para que lo fusilen revisen más y mejores ojos que los míos. A ver qué tal lo reciben. Para aplicarlo, hay que descomprimir las fuentes de Redmine, poner el parche en su directorio principal, y ejecutar esto:

patch -p1 < 0001-Redmine.pm-add-Git-smart-HTTP-support.patch

Un último detalle: Git necesitará nuestro usuario y contraseña para autenticarse. Una opción es clonar con http://usuario@host/git/repositorio, poniendo el usuario en la URL y metiendo la contraseña cada vez que haga falta, pero es muy incómodo: por desgracia, no guarda las contraseñas automáticamente como hace SVN. Otra opción es crear un fichero ~/.netrc (¡sólo legible por nuestro usuario!) con nuestro usuario y contraseña:

machine mihost
login miusuario
password mipassword

No me termina de gustar eso de tener mi contraseña guardada en la máquina, pero bueno, ya pasaba con SVN, así que supongo que es el precio a pagar por no tirar de SSH :-/.

Written by bluezio

24 de febrero de 2010 at 9:50

Publicado en Desarrollo

Tagged with , , , ,

  • Diseña un sitio como este con WordPress.com
    Comenzar