martes, 21 de enero de 2014

Sistema centralizado de tarifación telefónica - Gobierno de Córdoba


En el año 2000 ingresé a trabajar a la Dirección General de la Función Pública del Gobierno de Córdoba, específicamente en la Gerencia de Telecomunicaciones. La gerencia, entre otras responsabilidades, debía monitorear y controlar los enlaces de datos entre las dependencias del gobierno provincial, como así también los gastos telefónicos.

Entre las distintas dependencias de gobierno, existía (¿existe?) un probabilidad bajísima de encontrar dos equipos similares, ya sean de red de datos o de telefonía. La adquisición de nuevo equipamiento, que se suele realizar por licitación pública, depende mucho de la disponibilidad de equipos y de los precios del mercado al momento en que se lanza la licitación (existen además otros factores que exceden -y a veces superan en importancia- lo exclusivamente "técnico").

Las centrales telefónicas no escapan a esta lógica. En ese año, las centrales existentes constituían una verdadera arca de Noé tecnológica, lo cual a todas luces complica cualquier gestión posterior de estos equipamientos, porque obliga a mantener gente especializada para cada marca y/o modelo, o bien se deben pagar múltiples contratos de abono para soporte técnico, en relación directa con la variedad de centrales que se posea. Algunas de las centrales existentes en esa época eran:

  • Philips (Casa de Gobierno, Ministerio de la Solidaridad)
  • Ericsson (Central de Policía)
  • Panasonic (Ministerio de Finanzas, Dirección General de Rentas) 
Esta diversidad también era patente entre los programas instalados para consultar la información de tarifación. En Casa de Gobierno por ejemplo, existía una PC instalada con Windows XP conectada a la central mediante puerto serie RS-232. Debido al gran volumen de llamadas producidas por esa central, el programa de tarifación tardaba varias horas en generar un reporte completo. La patética performance de este sistema exigía la necesidad de lanzar un reporte antes de finalizar el turno de trabajo, para que esté listo cuando arrancara la actividad laboral al día siguiente. Esa falta de inmediatez en la adquisición de los datos afectaba la utilidad de los análisis que se pudieran hacer sobre los mismos.


Diseño del sistema de tarifación centralizado

Previo a la etapa de la implementación, y gracias a una estrategia de esa gestión, la mayor parte de los sistemas de Gobierno se habían concentrado en un solo sitio, conocido como "Supercentro". Esto exigía también que la mayoría de las dependencias de Gobierno deban estar conectadas mediante un enlace de datos redundante con ese sitio central. Esto permitió imaginar una solución que permitiera unificar toda la información del accounting de telefonía en un solo sitio.

El concepto natural aplicable, era un modelo de tres capas como el que se muestra a continuación:



El capturador debía subir la información de accounting a una base de datos ni bien esta se genere. Luego se puede acceder a la información almacenada mediante un desarrollo web con soporte CGI, de tal manera que la información solicitada se genere de manera dinámica. La implementación mediante web facilita el acceso a esta información,  ya que no exige la instalación de ningún programa cliente de base de datos específico en la PC del interesado. Además esto restringe el acceso directo a la base exclusivamente para el servidor web y los capturadores.

El sistema web cuenta con un esquema de acceso restringido, de tal manera que se debe
verificar la autenticación de los usuarios que acceden a la información. Además, teniendo en cuenta que existía un organigrama que establece una jerarquía arbolada entre las distintas áreas de Gobierno, esto define que tipo de información puede consultar cada usuario (solo puede ver información relacionada a su propia área o áreas dependientes).

La plataforma natural elegida para todos los elementos integrantes fue Linux, a pesar que en ese momento era inexplicable e injustificadamente resistido por los responsables de la dirección general. Cuando el esquema ya estaba funcionando y con algunos usuarios, la idea de rediseñar todo desde cero con una nueva plataforma se caía por su propio peso, así que no quedó otra alternativa que aceptar el desarrollo tal como estaba.

Capturador de datos de la central

La primer prueba de captura fue  realizada en la central de Casa de Gobierno. Agregamos un equipo que capturara la información de accounting, en paralelo a la PC existente, por lo cual hubo un tiempo de transición en que convivieron ambos sistemas de consulta. Construimos un cable que permitiera la recepción de la salida del puerto RS-232 por más de un receptor. Nuestro equipo de captura no iba a generar datos salientes, así que básicamente se comportaba como un "sniffer" del puerto RS-232 saliente de la central.

El equipo que realizaba la captura era una PC vieja, donada por la empresa de telecomunicaciones "CTI" (actualmente "Claro"). En ese momento, la empresa estaba migrando la tecnología de sus celdas, y estaba descartando PCs. La utilidad de estas PCs como estación de trabajo era limitada. Los modelos de PC eran dos: COMPAQ DESKPRO X466 y XE 450.

Sobre estas PCs marca COMPAQ se generó una imagen con sistema operativo Linux, distribución Slackware. Al funcionar esta PC exclusivamente como un capturador, se prescindía del uso de un monitor y teclado, aunque si era necesario que tuviera conectividad con la red de datos. Se podía acceder remotamente mediante SSH. La única tarea de utilidad del equipo era correr un programa que capturara la información de accounting emitida por la central, parseara los datos útiles de cada llamada, y los subiera por la red a un servidor de base de datos.

El capturador del puerto serie estaba basado en el programa "miniterm", mencionado en el "Linux Programmer's Guide". La operación de extracción de la información de accounting era distinta para cada modelo de central, ya que cada marca y modelo genera la información de accounting como mejor le parece. Por supuesto, no hay estándares en ese sentido, sumado al hecho de que fue bastante dificultoso acceder a la documentación de las mismas. Pareciera que el éxito de este tipo de esquemas se basa en retacear información a los clientes en la medida de lo posible.

Como ejemplo de la información de tarifación de la central philips de Casa de Gobierno, tenemos lineas como las siguientes:

...
* #0171101071720249375                            0474775                         13140000100431000050
* #0172208108881011         0000            000000001000048

* #0173101071720250474764     3514334394          9533                            31030000100931000011
* #0174101071720250474761     3514713779          9354                            31030000100634000038
* #0175101071720259354                            9391                            11140000000334000000
* #0176101071720259321                            0010007                         13140000000331000000
#017724394                0000            000000000000003
* #0178101071720259321                            0010009                         13140000000431000000
* #017924394                0000            000000000000004

...

La ubicación de la información es fija en cada linea, y debe cumplir con un formato prefijado. Por ejemplo, todas las lineas deben comenzar con '*' seguido de un espacio y '#'. A continuación  sigue "'01", y luego hay un número de secuencia que va desde "00" a "99". El siguiente caracter indica si el registro es información estandar (valor '1') o de accounting (valor '2').

Si es un registro estándar, debe tener un largo de 104 caracteres. Este tipo de registros provee información de la fecha: dos dígitos para año, mes, día, hora y minuto respectivamente. Además indica si la llamada es saliente hacia la PSTN (valor '3' en la posición 83), y si fue contestada (valor '1' en la posición 90). También incluye información del número originador de la llamada.

Si es un registro de accounting, debe tener un largo de 61 caracteres. Este tipo de registros informa la duración de la llamada en la posición 53, el número llamado en la posición 8, y la cantidad de pulsos de la llamada en la posición 47. Completa la información del registro estándar inmediatamente anterior (según la numeración de secuencia)


Ejemplo:



En esta primera versión, una vez que se extractaba la información útil de la llamada, se la subía a una base de datos en una operación concurrente, mediante un comando aparte.

Además de la transacción por red, se dejaba una copia del accounting en texto plano en el mismo capturador, por si hacía falta algún análisis posterior sobre la información en crudo. Aquellas lineas que no cumplieran con el formato, eran almacenadas por duplicado en un archivo separado para su posterior análisis.

Subida de los datos de accounting a la base de datos

En esta primera versión, los datos del accounting eran subidos de manera directa a una base de datos Mysql desde el capturador. El programa, también desarrollado en lenguaje "c", utilizaba la API correspondiente de Mysql para conectarse a la base remota.

En cuanto al diseño de la estructura de la base, hubo algunos errores producto de mi inexperiencia en el diseño de base de datos. El volumen de información almacenado era monstruoso, según la central. Teniendo en cuenta que no iban a existir consultas cruzadas entre distintas centrales, procedí a generar una tabla por separado para cada central, con el ánimo de agilizar cualquier consulta, o de restringir los problemas de performance solo a las centrales más grandes.

También generé un esquema de 4 tablas que definían la jerarquía del organigrama de las dependencias de Gobierno. En ese momento no existían más de 4 niveles, aunque nunca nadie tuvo claro cual era la conformación actual del organigrama, ya que las dependencias se creaban o desaparecían con una facilidad pasmosa; ya se sabe, a veces se quiere dar la impresión de que las cosas cambian si se generan algunas nuevas áreas o direcciones, se eliminan algunas otras, o se cambia la relación de dependencia entre ellas.

Web server + CGI

Los programas cgi fueron desarrollados en perl. En esta primera versión, el código HTML estaba embebido en el código perl.

La pantalla principal solicita usuario y contraseña:


La información de tarifación era solo uno de los desarrollos existentes en ese momento. Ingresando correctamente el usuario y la contraseña, se accedía a las opciones de reporte existentes:



La primera opción, mostraba las últimos 20 registros de la central seleccionada. Su principal utilidad era mostrar la dinámica de la información generada, e indicaba una dimensión del volumen de uso que tenía la central:



Gracias a una lista obtenida de la página de la CNC, se pudo determinar la localidad en base a la primera parte del número destino. Como regla general, el rango de números asignados varía entre 100 y 10.000 números, según la localidad que lo solicita. Algunos otros números especiales fueron cargados a mano.


Las siguientes 3 opciones proveen un listado completo del día, ordenado por distintos criterios:
  1. por hora, desde el más reciente al más antiguo:
  2.  por duración de la llamada:
  3.  por número de destino más llamado:
Se podía generar una distribución de llamadas en el último día, con la ayuda de la herramienta GNUPlot para los gráficos:

También se puede generar un reporte para un interno o un identificador específico:
se selecciona un rango de fechas, y muestra la lista correpondiente:

Por último, se pueden generar listados históricos por fecha y por central

el listado se ve como sigue:

El listado podía almacenarse en pdf, mediante el uso del comando "htmldoc":





Conclusión


Puede apreciarse la utilidad de las aplicaciones de código abierto para hacer desarrollos que integren distintas tecnologías. Sumado al software abierto y gratuito, se utilizó hardware de descarte. De hecho, el servidor inicial que integraba tanto la base de datos como el servidor web, también era una PC que estaba abandonada, aunque poseía más recursos que los equipos utilizados para captura (tampoco tanto más).

Con el tiempo, el uso de este sistema empezó a acrecentarse, y eso obligó a las autoridades a mejorar los recursos destinados para la etapa del servidor. Por cierto que la implementación de un sistema de estas características sin costo agregado en hardware o software, no es habitual en este tipo de organizaciones, ni siquiera atendiendo la coyuntura de ese momento (finales de 2001). En esa primera versión, las centrales consultadas eran tres: Casa de Gobierno, Instituto Pizzurno (Ministerio de la Solidaridad - Ministerio de Salud) y Dirección General de Rentas.

En sucesivas entradas, se irá describiendo la evolución que tuvo este desarrollo.

miércoles, 8 de enero de 2014

Live streaming en Ustream con Raspberry Pi + Camera board

La Raspberry Camera board es una placa adicional para Raspberry Pi, que de manera bastante sencilla nos permite agregar soporte de video a la mencionada placa. Solamente debemos conectar el nuevo dispositivo, actualizar el "firmware" de nuestro raspbian, y con eso tenemos la mayor parte del camino allanado. Pero vamos por parte.

Instalación y configuración de la camera board.

Los primeros pasos están bien descriptos en http://www.raspberrypi.org/camera, y básicamente son los siguientes:

  1. Conectar la placa con la RPi apagada, según las instrucciones del video http://www.youtube.com/watch?v=GImeVqHQzsE. Hay que prestar especial atención al sentido del cable.
  2. La cámara queda conectada de la siguiente manera:


  3. Actualizar los paquetes de Raspbian:
  4. sudo apt-get update
    sudo apt-get upgrade
  5. Ejecutar el programa de configuración de RPi:
  6. sudo raspi-config

    y seleccionar "camera" -> "enable"

    Salimos con "Finish". Reiniciamos la RPi.

Primeras pruebas con la cámara

La actualización del firmware nos provee de una serie de comandos adicionales para interactuar con la cámara. Uno de ellos es raspivid, que nos permite capturar video, mientras que raspistill nos permite capturar imágenes.

Algunos ejemplos de uso:

raspistill -o image.jpg (captura una imagen en el archivo image.jpeg)

raspivid -o video.h264 (captura un video de 5 segundos -duración por defecto- en el archivo video.h264).

raspivid nos permite enviar video a la salida por defecto (stdout), y esta funcionalidad es la que aprovecharemos para publicar el streaming.

Podrán encontrar muchos más ejemplos en la referencia mencionada antes. Entre ellos, existen algunos ejemplo sobre mecanismos de streaming utilizando netcat. En las referencias también encontrarán mecanismos para realizar streaming mediante la utilización de cvlc o ffmpeg como fuente de video, y vlc como cliente de streaming.

Utilizando Ustream como destino de nuestra transmisión

Ustream es un servicio muy utilizado para realizar transmisiones por Internet. No es el único en su tipo. Con una registración gratuita, podemos realizar nuestras primeras pruebas.

Una vez que ingresamos con nuestro usuario, podemos crear un "canal". Este canal posee algunas propiedades, entre ellas hay una que se llama "remote". Esta propiedad define el URL al que debemos apuntar con nuestra fuente de video, además de una "llave" que sirve para que nadie más usurpe nuestra transmisión.

La URL completa del destino de nuestra transmisión, está formada por ambos datos.


<url_de_tipo_rtmp>/<key>

Ejemplo:

rtmp://1.22114414.fme.ustream.tv/ustreamVideo/22114414/FKedARaaBeakurSacaADTufB5vaan7SL

Para enviar la salida del comando raspivid hacia Ustream, utilizaremos el comando avconv. La forma sería la siguiente:

raspivid -o - -w 460 -h 270 -t 9999999 |  avconv -r 10 -b 350k -i - -f flv
rtmp://1.22114414.fme.ustream.tv/ustreamVideo/22114414/FKedARaaBeakurSacaADTufB5vaan7SL

En este caso, enviamos un video de dimensiones 460x270 hacia el comando avconv. Este a su vez lo convierte en flv, y lo reenvía a Ustream.

Luego podremos acceder con un navegador a la dirección que Ustream asoció a nuestro canal:

http://www.ustream.tv/channel/nuestrocanaldeprueba

Algunas capturas de la transmisión:



Eso es todo.



Referencias:


http://www.raspberrypi.org/camera
http://www.mybigideas.co.uk/RPi/RPiCamera/
http://sonnati.wordpress.com/2011/08/30/ffmpeg-%E2%80%93-the-swiss-army-knife-of-internet-streaming-%E2%80%93-part-iv/
http://techzany.com/2013/09/live-streaming-video-using-avconv-and-a-raspberry-pi/

miércoles, 1 de enero de 2014

Acceder a Google Drive como una partición de red desde nuestro Debian Wheezy

Suele ser útil el disponer de espacio de almacenamiento on-line que nos permita acceder a ciertos archivos desde distintos hosts. De entre las múltiples opciones existentes, Google Drive es una buena opción, sobre todo si ya contamos con una cuenta de gmail.

En este caso, se instalará y configurará la aplicación google-drive-ocamlfuse para poder utilizar nuestra cuenta de Google Drive como almacenamiento. google-drive-ocamlfuse está basado en fuse, y permite montar y desmontar nuestro almacenamiento en Google Drive como habitualmente lo hacemos con otros sistemas de archivo de red.

Este desarrollo se encuentra alojado en github, por lo que es accesible por cualquiera que pretenda compilarlo desde sus fuentes. De cualquier manera, existen versiones pre-compiladas para Ubuntu que pueden ser utilizadas en Debian Wheezy.

Para ello, debemos disponer del comando add-apt-repository, que forma parte del paquete "python-software-properties". Si aún no lo tenemos instalado, debemos hacerlo:

sudo apt-get install python-software-properties

Ya estamos en condiciones de agregar el repositorio de Ubuntu que contiene los paquetes precompilados instalables de google-drive-ocamlfuse para Ubuntu:

sudo add-apt-repository ppa:alessandro-strada/ppa

Este comando genera el archivo "/etc/apt/sources.list.d/alessandro-strada-ppa-wheezy.list". Si inspeccionamos el contenido del archivo, veremos que la versión que utiliza para definir la entrada del repositorio ("wheezy" en nuestro caso), lo obtiene automáticamente del equipo donde se ejecutó el comando  "add-apt-repository". Lo cierto es que el paquete no está disponible para esa versión de Debian, y si lo está para distinta versiones de Ubuntu. Una versión de Ubuntu aproximadamente equivalente a wheezy, es "precise". Esta equivalencia está dada principalmente, por la versión de libc que utiliza una y otra versión.

Debemos editar el archivo "/etc/apt/sources.list.d/alessandro-strada-ppa-wheezy.list", y reemplazar las apariciones de "wheezy" por "precise". Luego actualizamos la información del repositorio.

sudo apt-get update

Ya tenemos disponible el programa google-drive-ocamlfuse si queremos instalarlo mediante el gestor de paquetes:

sudo apt-get install google-drive-ocamlfuse

Si se instaló correctamente, ya estamos en condiciones de utilizarlo.

Configuración

Al correr el programa google-drive-ocamlfuse por primera vez sin argumentos, se establece el mecanismo de autenticación que permitirá futuras ejecuciones sin mayores complicaciones:

google-drive-ocamlfuse

Esta primera ejecución, entre otras cosas, abre un navegador que nos solicita el ingreso en nuestra cuenta de gmail, para poder autorizar el acceso a esta aplicación. Si la autorización finaliza de manera exitosa, ya podemos utilizar el comando para montar y desmontar nuestro almacenamiento en Google Drive.

Podemos crear un directorio vacío que utilizaremos como punto de montaje para el almacenamiento:

mkdir ~/GDrive

Luego montamos nuestro almacenamiento remoto, de la siguiente manera:

google-drive-ocamlfuse ~/GDrive/

Una vez montado, podemos acceder con los comandos habituales para interactuar con un directorio. Ejemplo:


ls -l ~/GDrive/


Una vez finalizada la interacción con el almacenamiento remoto, podemos desmontarlo de la siguiente manera:

fusermount -u ~/GDrive/

Eso es todo.


Referencias:
http://gdfuse.forge.ocamlcore.org/