Test para ver el nivel en Asterisk y Digium Certified Asterisk Administrator

Después del curso, y segun nos habian comentado durante el mismo, en la actualidad existen dos tipos de titulaciones en Asterisk.

Digium Certified Asterisk Professional (dCAP), que es la mas popular y el que realmente te da acceso a un mundo laboral que tenga relacion con Asterisk. Pero por otro lado existe otro, aun no demasiado reconocido, con validez 4 años, llamado Digium Certified Asterisk Administrator (dCAA)

El examen consta de 60 preguntas, y un tiempo total para su realizacion de 11 minutos y 20 segundos (10 segundos por pregunta aproximadamente). No restan los fallos, pero hay que aprobar con un 80% de preguntas correctas, y es un formulario de tipo selección unica. No se cuantos intentos te dan, ni si se puede hacer en mas tiempo, porque eventualmente, lo aprobe a la primera y en el tiempo acordado. Para mi criterio, creo que es una prueba de nivel mas para el dCAP, tanto para probar los conocimientos obtenidos a traves de un curso Asterisk Fast Start (como el que vimos el año pasado), por lo que realmente tras un Asterisk Advanced, el aprobado deberia ser asegurado.

Otra cosa curiosa es que al aprobar te da un certificado como este, con validez de 4 años:

DCAA

Como creo que realmente el examen es una prueba de nivel, tras terminarlo trate de revisar mis respuestas señaladas (lo que es cierto que en solo poco mas de 11 minutos hay que intentar responder bastante rapido y a veces casi aleatoriamente, una vez marcada la respuesta y pulsado “siguiente”, ya no hay marcha atras para corregir, y al suspender no tengo muy claro si permiten volver a realizar el examen ipso-facto). Y aprovechando esto, decidi traducirlo y responderlo a modo de primer entrenamiento cara al proximo dCAP:

  1. ¿Qué hace el comando “make config” durante la instalación de Asterisk?
    a) Instala scripts que harán que Asterisk se arranque al inicio en las distribuciones soportadas por Asterisk
    b) Inicia una sesión interactiva para que el administrador pueda configurar detalles sobre  los usuarios PBX
    c) Instala ficheros de configuración en /etc/Asterisk
    d) Nada, make config no es un comando valido en este contexto
  2. ¿Porque DTMF utiliza dos tonos?
    a)      Para mejorar el reconocimiento sobre un solo tono
    b)      Ninguna razón en particular, es solo una decisión de estilo
    c)       Para conseguir un audio superior
    d)      No lo hace, se utiliza un solo tono
  3. En el contexto de Asterisk, ¿que significa CDR?
    a)      Customer Data Resource
    b)      Call Detail Record
    c)       Channel Data Review
    d)      Channel Driver Resource
  4. ¿Para cuál de los siguientes casos, Asterisk no utiliza SDP?
    a)      Renegociar el códec de audio utilizado en la llamada SIP mientras se encuentra activa
    b)      Configurar parámetros iniciales de los medios en una llamada SIP
    c)       Poner una llamada SIP en espera
    d)      Colgar una llamada SIP
  5. ¿Qué comando de CLI puede usarse para ver la configuración actual del Dialplan de Asterisk?
    a)      module show extensións.conf
    b)      core print Dialplan
    c)       module show pbx_config
    d)      dialplan show
  6. ¿Cuál de los siguientes no es un driver de canal en Asterisk?
    a)      CDR
    b)      SIP
    c)       Local
    d)      IAX
  7. ¿Qué fichero es utilizado para configurar los drivers del kernel para dispositivos DAHDI?
    a)      /etc/dahdi/dahdi.config
    b)      /etc/dahdi/system.conf
    c)       /etc/dahdi/chan_dahdi.conf
    d)      /etc/dahdi.conf
  8. ¿Con que protocolo VOIP es utilizado RTP?
    a)      IAX2
    b)      DAHDI
    c)       SIP
    d)      Zaptel
  9. ¿Qué ocurre cuando mandamos el comando a Asterisk “restart gracefully”?
    a)      Asterisk deja de recibir llamadas, y reinicia cuando las llamadas activas llegan a 0
    b)      Asterisk continua recibiendo llamadas, y reinicia cuando las llamadas activas llegan a 0
    c)       Nada. Esto no es un comando valido de Asterisk
    d)      Asterisk reinicia inmediatamente
  10. ¿Cuál es la localización por defecto de la música en espera de Asterisk?
    a)      /var/lib/asterisk/moh
    b)      /var/lib/Asterisk/holdmusic
    c)       /var/log/Asterisk/musiconhold
    d)      /etc/asterisk/musiconhold
  11. ¿Cuál de las siguientes afirmaciones es mas cierta con respecto al registro de un dispositivo en el contexto VOIP?
    a)      El registro permite a Asterisk saber dónde deben ir las llamadas destinadas al dispositivo
    b)      El registro es necesario para que el teléfono pueda chequear el Buzon de Voz
    c)       El registro es principalmente utilizado para asociar a una persona con un dispositivo
    d)      El registro es requerido para que solo los usuarios autentificados puedan hacer llamadas
  12. ¿Cuál es la diferencia entre las aplicaciones VoiceMail y VoiceMailMain en Asterisk?
    a)      VoiceMailMain se utiliza para grabar una mensaje de alguien, y VoiceMail se utiliza para que una persona escuche los mensajes recibidos
    b)      VoiceMail se utiliza para grabar una mensaje de alguien, y VoiceMailMain se utiliza para que una persona escuche los mensajes recibidos
    c)       VoiceMail es utilizado cuando los mensajes son guardados en una base de datos o en una almacen IMAP, VoiceMailMain es utilizando cuando los mensajes han sido guardados en el disco duro
    d)      Nada de lo anterior, las dos aplicaciones son intercambiables
  13. ¿Cuál es el ancho de banda requerido para una llamada bidireccional con G.711?
    a)      ~160Kbps
    b)      ~80Kbps
    c)       ~64Kbps
    d)      ~8Kbps
  14. ¿Cuál de los siguientes, no es una cadena de llamada valida en Asterisk?
    a)      Dial(SIP/100,30)
    b)      Dial(30,SIP/100)
    c)       Dial(SIP/100)
    d)      Dial(SIP/100&SIP/200)
  15. Sobre configuraciones de red ¿Qué es la latencia?
    a)      El retraso desde que un paquete es enviado  hasta que es retrasmitido
    b)      El retraso desde que un paquete es trasmitido hasta que es recibido
    c)       El retraso causado por la transcodificacion de audio?
    d)      El retraso entre la marcación y el timbre
  16. ¿Qué configuración prevendrá Asterisk de negociar entre dos canales SIP de enviarse RTP directamente entre ambos?
    a)      canreinvite = no
    b)      trunk = no
    c)       canreinvite = yes
    d)      canreinivite = never
  17. ¿Para que sirve el comando ‘!’ en la línea de comandos de Asterisk?
    a)      Para nada. El comando ‘!’ no es un comando valido en el CLI de Asterisk
    b)      Rejecuta el comando anterior de nuevo
    c)       Ejecuta un comando Shell de Linux
    d)      Confirma que deseas ejecutar el comando especificado
  18. ¿Cuál de las siguientes estrategias NO puede utilizarse en Asterisk con colas?
    a)      Llamar al agente disponible que haya recibido más llamadas
    b)      Llamar a todos los agentes a la vez
    c)       Llamar a un agente aleatorio
    d)      Llamar al agente disponible que haya recibido menos llamadas
  19. ¿Qué es un ‘call file’ en Asterisk?
    a)      Un fichero de comandos que inicia una llamada saliente
    b)      Un fichero temporal que se crea en /dev/ para un canal activo en Asterisk
    c)       Un fichero con registros CDR para facturación
    d)      Un fichero generado por cada buzon de voz para almacenar información como CallerID, hora, etc
  20. ¿Cuál de las siguientes aplicaciones NO esta por defecto en un Dialplan de Asterisk
    a)      Hold()
    b)      Dial()
    c)       Hangup()
    d)      Playback()
  21. ¿Cuál de los siguientes codecs puede ser utilizado por Asterisk para grabar un mensaje del buzon de voz en Asterisk?
    a)      OGG
    b)      MP3
    c)       GSM
    d)      G.729
  22. ¿Cuál de las siguientes líneas en el extensions.conf NO tiene un error de sintaxis?
    a)      exten => 1,n,Dial,SIP/6000
    b)      exten => 1,n,(dial),Dial(SIP/6000)
    c)       exten => 1,n(dial,Dial(SIP/6000)
    d)      exten => 1,n(dial),Dial(SIP/6000)
  23. ¿Cuál de los siguientes puerto(s) debe ser redirigido en un firewall para permitir que el trafico RTP pueda alcanzar Asterisk?
    a)      5060
    b)      8000-10000
    c)       12000-20000
    d)      Aquellos puertos especificados en el archivo de configuración de Asterisk rtp.conf
  24. ¿Cuál de las siguientes extensiones especiales NO está reconocida por Asterisk?
    a)      fax
    b)      i
    c)       T
    d)      r
  25. ¿Cuál es la ubicación por defecto para los archivos de sonido de Asteirsk?
    a)      /var/log/asterisk/sounds
    b)      /etc/asterisk
    c)       /var/lib/asterisk/sounds/
    d)      /usr/lib/Asterisk/sounds/
  26. ¿Cuál de los siguientes, incluirá el contexto [local] en otro contexto?
    a)      #include => local
    b)      Switch => local
    c)       context => local
    d)      include => local
  27. ¿Cuál de los siguientes es el mensaje inicial enviado por un PRI cuando se realiza una llamada saliente?
    a)      CONNECT
    b)      SETUP
    c)       DIAL
    d)      INVITE
  28. ¿Cuál es el máximo numero de participantes posibles en una sala de conferencias de Meetme de Asterisk?
    a)      30
    b)      1000
    c)       240
    d)      No hay limite
  29. ¿Cuál de los siguientes comandos creara una conexión CLI a una instancia de Asterisk corriendo en el transfondo?
    a)      asterisk
    b)      asterisk –x
    c)       asterisk –r
    d)      Asterisk –vvvvvgc
  30. ¿Cuál de los siguientes representa la forma correcta de dereferenciar una variable en Asterisk?
    a)      {$VARIABLE}
    b)      $__VARIABLE
    c)       $[VARIABLE]
    d)      ${VARIABLE}
  31. ¿Qué hara la siguiente línea del DialPlan?
    exten => 1000,1,GotoIf($[${EXTEN}>1000]?hangup:continue)
    a)      Continua hacia la prioridad continue porque la expresión es falsa
    b)      Nada, es una línea invalida de Dialplan
    c)       Continua con la prioridad hangup porque la expresión es cierta
    d)      Cuelga la llamada, porque la expresión es cierta y el comando cuando es verdadero es el cuelgue
  32. ¿Cuál de los siguientes NO es un códec de audio?
    a)      G.711
    b)      H.323
    c)       G.729
    d)      GSM
  33. ¿Cuál de los siguientes modelos describe exactamente la sintaxis exacta de un Dialplan?
    a)      exten => contexto,extensión,prioridad
    b)      exten => extension, prioridad, aplicacion
    c)       extension => prioridad, etiqueta, aplicación
    d)      exten => extension, prioridad, etiqueta, aplicación
  34. ¿Cuál de los siguientes no es una variable de canal automáticamente ajustada por Asterisk?
    a)      CONTEXT
    b)      UNIQUEID
    c)       CHANNEL_NAME
    d)      TIMESTAMP
  35. ¿Qué puerto(s) pueden ser redirigidos en un firewall para permitir que el trafico SIP llegue a Asterisk?
    a)      1000-2000
    b)      443
    c)       5060
    d)      22
  36. ¿Qué método de señalización debe utilizar un dispositivo FXS?
    a)      Session Initiation Protocol
    b)      ISDN
    c)       Foreign eXchange Office
    d)      Foreign eXchange Subscriber
  37. ¿Qué es DUNDi?
    a)      Un registro global de ITSPs
    b)      Un módulo de driver de canal en Asterisk
    c)       Una herramienta para simplificar el enrutamiento de multiples sitios
    d)      Una marca de PBX de Australia
  38. ¿Cómo se utiliza SDP en Asterisk?
    a)      SDP no se utiliza en Asterisk
    b)      Para transportar los medios  en una llamada SIP
    c)       Para inivitar a un individuo a una llamada SIP
    d)      Para negociar/describir los medios en una llamada SIP
  39. Por defecto, ¿dónde se almacenan los ficheros de log en Asterisk?
    a)      /etc/asterisk/logs
    b)      /var/lib/Asterisk/logs
    c)       /usr/log/asterisk
    d)      /var/log/Asterisk
  40. ¿Qué fichero de configuración de Asterisk especifica los puertos utilizados por los medios en una llamada SIP?
    a)      ports.conf
    b)      rtp.conf
    c)       sip.conf
    d)      media.conf
  41. ¿Qué hara la siguiente línea de dialplan?
    exten => s,1,Set(COUNT=$[${COUNT}+1])
    a)      Nada, es una línea invalida para el Dialplan
    b)      Almacenar la cadena “$[${COUNT}+1]” en una variable llamada COUNT
    c)       Poner el valor de COUNT  a 1, porque la expresión se evalua como verdadera
    d)      Limpiar el valor de la variable COUNT  a su valor anterior mas 1
  42. ¿Cuál de las siguientes aplicaciones del Dialplan hara que Asteirsk NO “escuche” una entrada DTMF?
    a)      Read()
    b)      Wait()
    c)       Background()
    d)      WaitExten()
  43. ¿En que fichero de configuración se manejan los huecos de parking de llamadas?
    a)      callparking.conf
    b)      extensions.conf
    c)       parkinglots.conf
    d)      features.conf
  44. ¿Cómo se utiliza la aplicación Record en Asterisk?
    a)      Para monitorizar otro canal en tiempo real
    b)      Para imprimir contenidos de un registro de base de datos en el CLI de Asterisk
    c)       Para crear un fichero de sonido en el disco con el audio recibido de un canal activo
    d)      Para reproducir los contenidos de un registro de base de datos en un canal de Asterisk utilizando un convertidor de texto a voz.
  45. ¿Cuál de los siguientes no es un soporte de CDR valido por defecto en Asterisk?
    a)      Hoja de cálculo de Excel
    b)      Archivos .csv
    c)       Servidor RADIUS
    d)      Base de datos Relacional
  46. ¿Qué opción de configuración del sip.conf debe realizarse para permitir que un dispositivo se registre contra Asterisk?
    a)      host = dynamic
    b)      host = unknown
    c)       address = any
    d)      ipaddress = dynamic
  47. ¿Bajo qué licencia de software libre está disponible Asterisk?
    a)      LGPL
    b)      BSD
    c)       GPLv2
    d)      GPLv3
  48. ¿En cuál de los órdenes siguientes, los códecs consumen de menos ancho de banda a mayor ancho de banda?
    a)      GSM, G.711, G.729
    b)      G729, G.711, GSM
    c)       G.711, GSM, G.729
    d)      G.729, GSM, G.711
  49. ¿Cuál de los siguientes NO es una forma para generar una llamada de otra forma que no sea un teléfono?
    a)      A través del Asterisk Manager Interface
    b)      A través de un fichero creado específicamente y copiado en /var/spool/asterisk/outgoing
    c)       A través de Asterisk Realtime Architecture
    d)      A través de un comando de CLI “console dial”
  50. En un sistema típico Linux, ¿Cuál de los siguientes comandos NO se utiliza para saber la carga media del sistema?
    a)      Utilizando la herramienta “load”
    b)      Viendo los contenidos de /proc/loadavg
    c)       Utilizando la herramienta “top”
    d)      Utilizando la herramienta “uptime”
  51. ¿Cuál de los siguientes, NO es un método de almacenaje valido para un buzón de voz en un sistema Asterisk sin modificar?
    a)      En la RAM
    b)      Via IMAP
    c)       Via ODBC
    d)      En el sistema de archivos
  52. ¿Sobre qué usuario debería funcionar Asterisk?
    a)      root
    b)      asterisk
    c)       nadie
    d)      Asterisk debería ser lanzado desde cualquier usuario
  53. En Asterisk, ¿Cuál es la diferencia entre formato y códec?
    a)      El formato describe el protocolo usado, y el códec describe los medios usados
    b)      El formato traduce los medios guardados en disco, y el códec traduce los medios a ser trasmitidos en el canal
    c)       El formato describe los medios entrantes y el códec  describe los medios salientes
    d)      El formato describe los medios de video, y el códec describe los medios de audio
  54. ¿Qué archivo de configuración controla los “paths” del sistema que Asterisk utiliza para guardar los modulos, CDR, y logs?
    a)      files.conf
    b)      directory.conf
    c)       asterisk.conf
    d)      logger.conf
  55. ¿Cuál de los siguientes NO es una aplicación de Asterisk comúnmente usada para propósitos de Debug?
    a)      Jitter
    b)      Echo
    c)       Milliwatt
    d)      NoOp
  56. ¿Cuál de los siguientes NO es cierto acerca de Asterisk y DAHDI?
    a)      Asterisk y DAHDI están disponibles bajo licencias Open Source
    b)      Asterisk y DAHDI trabajan juntos para ofrecer interfaces físicas a un sistema PBX
    c)       Asterisk y DAHDI están patrocinados y mantenidos por Digium
    d)      Asterisk y DAHDI solo son compatibles cuando los mismos números de versión son utilizados para ambos
  57. ¿Cuál de los siguientes NO es un fichero de configuración estándar para Asterisk?
    a)      pri.conf
    b)      chan_dahdi.conf
    c)       sip.conf
    d)      iax.conf
  58. ¿Qué es el “jitter”?
    a)      La latencia entre dos puntos VOIP
    b)      Cambios en el volumen/ganancia provocados por la transcodificación
    c)       Variaciones en la latencia entre dos puntos VOIP
    d)      El eco en los enlaces VOIP
  59. ¿Cuál de los siguientes es la sintaxis correcta para configurar un canal SIP que solo permita el códec GSM?
    a)      disallow = all, allow = all
    b)      deny=ulaw,alaw,g729,g723
    c)       allow =gsm
    d)      permit = gsm, deny = all
  60. ¿Cuál es la diferencia entre las salidas de “verbose” y “debug” en el Asterisk CLI?
    a)      La salida Verbose es acerca de los canales, y la salida Debug es acerca de otras partes de Asterisk
    b)      La salida Verbose, suelen ser mensajes de estado útiles para administradores mientras que la salida Debug suelen ser mensajes útiles para desarrolladores
    c)       No existe diferencia. Ambos tipos de salida de consola son lo mismo.
    d)      La salida Debug, suelen ser mensajes de estado útiles para administradores mientras que la salida Verbose suelen ser mensajes útiles para desarrolladores

A continuación, las soluciones que yo creo que son las correctas. Me gustaría que alguien experimentado las revisase tambien, y comentase cuales cree que pueden estar mal, o de las que tengo dudas, que opina al respecto:

Solución 1: a)
Solución 2: a)
Solución 3: b)
Solución 4: d)
Solución 5: d)
Solución 6: a)
Solución 7: b)
Solución 8: c)
Solución 9: a)
Solución 10: a)
Solución 11: a)
Solución 12: b)
Solución 13: c)
Solución 14: b)
Solución 15: b)
Solución 16: a)
Solución 17: c)
Solución 18: a)
Solución 19: a)
Solución 20: a)
Solución 21: c)
Solución 22: d)
Solución 23: d)
Solución 24: d)
Solución 25: c)
Solución 26: d)
Solución 27: b)
Solución 28: b)
Solución 29: c)
Solución 30: d)
Solución 31: a)
Solución 32: b)
Solución: 33: b)
Solución 34: c)
Solución 35: c)
Solución 36: c)
Solución 37: c)
Solucion 38: d)
Solución 39: d)
Solución 40: b)
Solución 41: d)
Solución 42: b)
Solución 43: d)
Solución 44: c)
Solución 45: a)
Solución 46: a)
Solución 47: c)
Solución 48: d)
Solución 49: c)
Solución 50: a)
Solución 51: a)
Solución 52: b)
Solución 53: b)
Solución 54: c)
Solución 55: a)
Solución 56: d)
Solución 57: a)
Solución 58: c)
Solución 59: c)
Solución: 60: b)

Advanced Asterisk. Days 4 y 5

Ya entrando en la recta final, continuamos con el tema de ayer de conexiones de tarjeteria y PSTN.

Primero van los conceptos teoricos sobre los tipos de sistemas digitales de telefonia Americanos (T1), Europeos (E1), las señalizaciones, los canales, servicios implementados como RDSI (ISDN), codificacion de las señales… realmente son temas que para un caso en concreto de uso hay que tenerlos claros.

Un ejemplo practico seria la interconexion duplex entre una centralita Asterisk y una Alcatel con tarjeteria en ambos lados. Para la comunicación de mensajes a nivel de servicios digitales, se implementa un protocolo de señalización llamado Q.931, pero mas concretamente de un protocolo variante especifico para esta funcionalidad de interconexión de centralitas, llamado Q.SIG.

Ahora vamos a la parte practica de configuracion, hay que considerar que existen dos tipos de configuraciones, la especifica para Estados Unidos y otra para Europa, en este caso voy a intentar de ir planteando las dos, porque cara a Digium la que se utiliza es la EEUU, pero para nuestros casos practicos seguramente sea la Europea.

Configuracion del /etc/dahdi/system.conf

Primero tenemos que configurar cada uno de los puertos

span = <numero_del_puerto>,<fuente_de_sincronizacion>,<line_built_out>,

Ejemplo americano:

span = 1,1,0,esf,b8zs

Ejemplo europeo:

span = 1,1,0,ccs,hdb3,crc4
– El 1 primero, es el numero del canal

– El 1 es para ser receptor de la fuente, y el 0 para ser el emisor
– El siguiente 0, es para no amplificar la señal si los cables son normales, o 1 si son demasiado largos (el cable que nos llega del operador esta en una ubicación muy apartada de donde esta nuestro equipo)
– ESF/CCS, las señalizaciones, americana y europea respectivamente
– B8ZS, y HDB3 son las codificaciones
– Finalmente CRC4, el sistema de control de errores

Luego se configuran, los bchan (canales de datos) y el dchan (canal de señalizacion)

bchan = 1-23
dchan = 24

– En modo americano

bchan = 1-15,17-31

dchan = 16

– En modo europeo

Y luego el loadzone = es/us y defaultzone=es/us es especialmente importante cuando se tratan de tarjetas digitales.

En el fichero /etc/dahdi/modules, hay que levantar el modulo especifico de la tarjeta de T1/E1 llamado wcte12x (primario con 1 puerto T1/E1 o wct4xxp (2 o 4 puertos T1/E1), y si hablamos de puertos BRI seria el modulo wcb4xxp

Finalmente se configura el chan_dahdi.conf muy parecido a las tarjetas analogicas Podemos empezar a amplicar elsistema de “contextos” para este fichero de configuracion.

[channels]

[Primarios]
callerid=asreceived
contexto=llamadas_entrantes
signaling= //Aqui va la configuracion especifica de los primarios, hay opciones como pri_cpe (si recibimos de un operador) o pri_net (si somos los emisores de la señal)
switchtype = //Otro especifico, teoricamente existen multiples tipos de primarios, la red National, la red de AT&T en estados unidos, o la unificada de Europa EuroISDN, los valores posibles, “national”, “euroisdn”, etc. Y en el caso que estemos interconectando dos centralitas, por ejemplo a la Alcatel que hablabamos antes, pues aquí se pone “qsig”
dahdichan=1-23 //los canales de datos que antes configuramos en el system.conf, caso Americano
dahdichan=1-15,17-31 //los canales caso Europeo
group = 1 //esto es practico para no tener que estar definiendo un canal en el extensions.conf para cada canal, se utiliza un “generico” que se aplica al “grupo de canales”, y se define como gX (siendo X el numero del grupo). Para este ejemplo una opcion seria: DAHDI/g1

Ademas un tema importante de los grupos es que se pueden configurar los mecanismos de selección de canal dentro del grupo. Se pueden aplicar distintas tecnicas de selección, como la secuencial empezando por el canal primero, por el final, metodo round-robin, etc. Esto se configura, al configurar el tipo de grupo en el extensions.conf. Antes puse DAHDI/g1, pero podria ser G1, r1 y R1 (la r es el metodo Round Robin)

Una gran diferencia con respecto a las lineas analogicas, es que las llamadas no entran a la extension start del dialplan, sino entran al telefono (DID) al que es llamado por tanto en el dialplan la extension “entrante” se define con el numero del DID

Ejemplos:

exten => 919191919,1,Dial(SIP/mitelefono)

exten => 929292929,1,Dial(SIP/tutelefono)

Pero esto ya lo vimos cuando trabajabamos con el Gateway de puertos BRI, Epygi, que tenia un mecanismo muy similar aunque se configurara externamente.

– Fax en Asterisk

A raiz de la version 1.8 mejoro bastante el soporte “nativo” para FAX con respecto a las versiones anteriores, tanto a nivel Passthrough por el protocolo T.38, como utilizando la maquina Asterisk como gestora de FAX. Pero realmente para esto segundo, el soporte de FAX por Asterisk es limitado o de pago si queremos utilizarlo en produccion. Aquí hay una explicacion detallada del tema

En nuestro caso ya explicamos como tener un sistema completo y libre utilizando Hylafax con el IAXModem bastante efectivo. A raiz del mensaje de Enesoluciones (ahora Fundacion Guadalux) pense que el sistema nuevo de Asterisk sustituiria el Hylafax brutalmente, pero parece que no va a ser asi de momento,por el tema este de las licencias de pago que hablaba (aunque al parecer Digium ofrece una unica licencia gratuita para solo 1 llamada concurrente, que seguramente en muchas instalaciones para PYMES sea suficiente).

– Asterisk Database (AstDB)

Asterisk implementa un sistema de bases de datos muy sencillo para almacenar informacion relativamente poco compleja. Es mas comodo que tener que andar trabajando con conectores ODBC y demas historias siempre y cuando busquemos aplicaciones concretas donde haga falta almacenar valores y acceder a ellos facilmente, pero especificamente del propio sistema de configuracion de Asterisk (ejemplo las Listas Negras de llamantes, familia blacklist)

Las funciones de lectura y escritura son extremadamente sencillas (totalmente integradas en el sistema Asterisk). Basicamente son usos de la aplicación Set y manejo de variables pero con la funcion DB() cubriendo esta nueva “variable”.

La variable esta compuesta por familia/clave/valor por ejemplo users/mitelefono/SIP/mitelefono

En este caso la clave mitelefono dentro de la familia, users, tendra el valor SIP/mitelefono (que por ejemplo es el canal SIP que utiliza nuestro telefono SIP).

Ejemplos:

Asignar a un registro de la base de datos: Set(DB(users/mitelefono)=’SIP/mitelefono’)

Consultar el registro: ${DB(users/mitelefono)}

Con todo esto parece que podemos “recortar” en variables globales dentro de los ficheros de configuracion basicamente. A lo mejor seria interesante montar algo serio que utilice esto a mayor escala como lo que comentaba esto de los Blacklist, aunque realmente tampoco tendra mucho misterio, algunas lineas. Me lo apunto como futura practica.

– Ultimo dia. 5: Seguridad en Asterisk

Para finalizar, y dar cierre al Asteirsk Advanced, el ultimo dia se trataron multiples temas relacionados con la seguridad en Asterisk

Sobre este tema tengo que hacer un comentario: justamente, ahora que estoy bastante desconectado del mundo “tecnologico” a nivel profesional, no tengo tanto acceso como antes a tarjeterias, equipos de trabajo y demas historias que me hacian el mundo facil en el progreso Asterisk.  Pero concretamente acerca de la seguridad en Asterisk, supuestamente el sistema mas “peligroso” en el que montar un Asterisk es abierto a Internet. Por ello en las proximas entradas, voy a estar focalizando en esta idea, ya que mi forma de “progresar” de ahora en adelante va a ser montando una maquina Asterisk en Casa y ofreciendo servicios concretos a individuales, a mi empresa (de forma altruista) y a otras empresa que quiza pudieran interesarme por el potencial (¿patrocinio o algo asi?) que pudieran ofrecerme (especialmente por los recursos economicos que pudieran aportar al tema).

El tema de seguridad en Asterisk tomaba dos perspectivas: el tipo de securizacion que habia que tomar en consideracion por niveles de “inseguridad” (desde el montaje de una maquina aislada de la red, hasta el montaje de una maquina publicado a internet), y por otro lado, todos la securizacion de todos los componentes del sistema (desde los accesos a la propia maquina hardware, pasando por el sistema operativo, hasta el mismo dialplan).

– Conclusiones y Consideraciones Finales sobre el Curso

Como comentaba el segundo dia debo determinar y concluir que el curso ha satisfecho mis expectativas, ya que realmente el interes de hacer un curso de este calibre, no ha suele ser tanto, la cantidad de informacion recibida, sino la posibilidad de “expandir” conceptos acerca de la especialidad en concreto que viene a tratarse, a traves de los profesores y los compañeros. Hay que considerar que el precio realmente no cubre solo las horas de enseñanza, sino tambien las horas de “relacion”. Es cierto que para “conectar” con otros individuales especialistas o no especialistas en un sector, no es realmente necesario hacer un curso, y que para el aprendizaje por ese precio se podrian llegar a conseguir incluso, horas de enseñanza particulares por internet pactando con algun profesional un precio por hora (algun dCAP) sin excesiva dificultad. Pero mas alla de estas dos posibilidades, y la primera en particular, tambien hay que considerar que el perfil de alumno que va a un curso de este tipo, no suele ser de “Lurker” ya que al costar (bastante) dinero, suelen ser o aportes profesionales (empresas que quieren formar a sus trabajadores especialistas), o aportes personales (autonomos o como yo esta vez, especialmente interesados en el sector).

Proxima parada: Examen dCAP. No se donde sera, pero desde hoy ya toca empezar a practicar y estudiar como el que mas. Segun parece, por los alumnos que se presentaron, el nivel del examen practico ha aumentado a practicamente al doble de dificultad que las ultimas convocatorias, y sobre el teorico no pude enterarme, ya que tuvimos que irnos a comer porque el examen se alargaba demasiado.

Asterisk Advanced. Day 3

Hoy voy a hacer una prueba, escribir un articulo durante la clase a modo “Inline”. Seguramente salga un articulo demasiado extenso pero al menos, lo máximo completo.

– Teoría de Macros en el DialPlan

En primer lugar un tema que no hemos visto hasta la fecha y es crucial para configuraciones de dialplan repetitivas, las Macros.

Dos conceptos basicos

Las macros se componen del contexto del Macro [macro-<nombredelmacro>]

Solo tienen una extension, la “s”
exten => s,1,Answer()
same => n,Hangup

Por otro lado, las Macros se ejecutan desde el Plan de Marcacion, como una aplicación cualquiera con el formato Macro(<nombredelmacro>, <argumento1>, <argumento2>, etc)

Luego dentro del contexto Macro para poder utilizar esos argumentos llamados se utilizan las variables especificas de las macros ${ARG1}, ${ARG2}, etc

Ejemplo:

[extensiones]
exten => 100,1,Macro(prueba,SIP/mitelefono, 30)

[macro-prueba]
exten => s,1,Dial(${ARG1},${ARG2})

Aparte disponemos de variables especificas de las Macro. ${MACRO_CONTEXT}, ${MACRO_EXTEN} y ${MACRO_PRIORITY}. Sirven para saber dentro de la macro, que contexto, que extensión y que prioridad llamó a la Macro.

Un ejemplo, si utilizamos un Buzon de Voz, que coincide con el numero de extension pues podriamos utilizar ${MACRO_EXTEN}:

[extensiones]
exten => 100,1,Macro(prueba,SIP/mitelefono, 30)

[macro-prueba]
exten => s,1,Dial(${ARG1},${ARG2})
exten => n,VoiceMail(${MACRO_EXTEN})

A partir de aquí ya podemos dar “rienda suelta” a la imaginacion y poder simplificar nuestro trabajo de escritura de tareas repetitivas.

– Asterisk Realtime

Ya conocemos esto de artículos anteriores, como el uso del Web-MeetMe (configuraciones de salas de conferencia directamente desde la Web, a través de bases de datos en “tiempo real” (realtime).

Pero ahora una visión un poco mas práctica de como se trabaja con Realtime, ya que realmente el Web-Meetme siguiendo los pasos venia prácticamente preparado paso por paso y no podíamos entender que estaba haciendo realmente a nivel interno.

La utilidad de Realtime sobre configuraciones en ficheros de texto, es simplemente el hecho de poder introducir modificaciones constantes de una forma ultra-rapida (mediante un interfaz web por ejemplo que acceda a la base de datos).

Un ejemplo tipico: en la web vemos el listado de usuarios, con un boton para borrarlos cuando los damos de baja, y luego un mini formulario en el que ponemos el usuario y la contraseña y damos de alta una extensión inmediatamente. No habria que estar accediendo al servidor, accediendo al fichero de texto, editándolo, guardando, recargando el modulo, etc…

En configuraciones estáticas (situaciones en las que rara vez se cambia una extension por ejemplo), es poco practico por que puede salir mas caro el collar que el perro. Pero si un dia nos da por diseñar una interfaz web sencilla, y una base de datos (fichero .sql) que precargue nuestros valores default, podriamos implementar esto en tiempo record y podríamos tenerlo siempre presente en todas nuestras instalaciones (quizá algún día lo plantee esto como un articulo, muchos temas ya tengo pendientes conforme avanzamos en el mundo de Asterisk).

Un primer inconveniente que encontramos, es que Asterisk pretende centralizar todas las conexiones a bases de datos a traves de una capa de abstraccion como ODBC, es decir que los conectores directos nativos como MySQL y PostgreSQL tienden a su desaparicion. Para los no demasiado experimentados en el mundo ODBC esto podria ser un inconveniente a corto plazo.

Si recuerdan, el Web-Meetme lo hacia todo a traves de ODBC asi que este problema lo salvan (lo que no salvan que Meetme tiende a desaparcer tambien en favor de ConfBridge (nueva aplicación para conferencias sin necesidad de timing, tambien hablaremos de ella en un futuro).

Ahora sobre la configuración los ficheros involucrados

En primer lugar /etc/asterisk/extconfig.conf necesitamos añadir una linea del tipo
<nombredelaconfiguracion> => <driver>,<nombrebasededatos>,<nombretabla>

En el caso ejemplo del Web-Meetme era:
meetme => odbc,meetme, booking

El segundo fichero es el /etc/asterisk/res_config.conf

[nombrebasededatos]
enabled => yes // Esta activada la conexion
dsn => el Data Source Name del driver ODBC
pre-connect => yes // La conexión se ejecuta al arrancar Asterisk
username => usuario de la base de datos // En caso que conectemos por Puerto a la base de Datos, como en bases remotas
password => password de la base de datos // Lo mismo que lo anterior

En el ejemplo que estamos siguiendo:

[meetme]
dsn => meetme (este es el contexto que creamos antes en el sistema)
username => asterisk (supuestamente va a ser nuestro usuario para asuntos de Asterisk y servidor de base de datos)
password => asterisk (o la que le pusiéramos)
pre-connect => yes
enabled => yes

Ahora la configuracion del driver odbc en el sistema, /etc/odbc.ini

[meetme]
Description = ODBC para MySQL // Una descripcion cualquiera
Driver = MySQL // El driver ODBC que utilizamos, en este caso para MySQL por el tema ese que va a tender a desaparecer que comentábamos antes
Server = localhost // Servidor donde esta la base de datos
Database = meetme // Nombre de la base de datos con la que trabajaremos
Port = 3306 // Puerto de la base de datos
User = asterisk // En caso que conectemos por puerto en vez de por Socket
Password = asterisk // En caso que conectemos por Socket
Socket = /var/run/mysqld/mysqld.sock // Por aquí conectamos por Socket

Y finalmente /etc/odbcinst.ini

[MySQL]
Description = MySQL ODBC MyODBC Driver
Driver = /usr/lib/odbc/libmyodbc.so // librería ODBC del Driver MySQL
Setup = /usr/lib/odbc/libodbcmyS.so // librería ODBC de Configuración MySQL

Solo quedaria configurar la tabla y base de datos y ya preparado.

Algunas consideraciones adicionales: para reducir el numero de peticiones a cache, el fichero de configuracion del modulo que estamos convirtiendo en “RealTime” introducimos la siguiente variable: rtcachefriends=yes

De aquí pueden surgir multiples ideas prácticas que me gustaria probar personalmente y dedicar un articulo especifico con mis resultados, como por ejemplo, crear una funcion en func_odbc.conf para consultar algo especifico de una base de datos externa para tratarlo a traves del DialPlan, como por ejemplo consultar el telefono de un Cliente.

– CDR y CEL

Esta parte trata sobre como se gestiona CDR (Registro de Detalles de Llamada) y la nueva implementación mas detallada del registro CEL, en el que es posible ver a nivel de flujo de llamada de DialPlan, no solo a nivel de canal. La verdad es que es meramente informativa con informacion sobre los campos que se utilizan, y algunas aplicaciones de dialplan para edicion, pero realmente merece un articulo bastante amplio para poder entrar en detalle incluso algun mecanismo para extraer informacion como vimos en el articulo de CDR-Stats, una gran aplicación para poder visualizar los datos de forma bastante generica (y recuerdo que quede en montar un software para analizar llamadas pero mas en detalle para un proposito en concreto).

– El mundo de las Tarjetas Analogicas

Ya dedique varios articulos a este tema cuando empece a trabajar con la tarjeta TDM410P como el siguiente y la segunda parte del mismo.

Algunos conceptos novedosos y no vistos hasta la fecha:

Sobre la tecnologia Analogica, existen tres posibles de sistemas de señalizacion, (en el fichero chan_dahdi.conf) ground start (en desuso), loop start (tambien en desuso) y kewl start (sistema mas utilizado en la actualidad, 99% de los casos).

Otra novedad que trae la version 1.8 es la posibilidad de crear contextos en el chan_dahdi.conf y tener por ejemplo un contexto generico [channels] donde especificar ciertos argumentos especificos de la tecnologia analogica (que eran los que soliamos definir antes del channel => cuando utilizabamos un modulo FXO

Ejemplo:

[channnels]
usecallerid = yes
transfer = yes

[telefono-analogico]
callerid = “Telefono Analogico” <1001>
context= extensiones
signaling = fxo_ks
dahdichan = <el_canal_que_definimos_en_/etc/dahdi/system.conf>

[linea-analogica]
callerid=asreceived
context = llamadas_entrantes
signaling = fks_ks
dahdichan = <el_canal_que_definimos_en_/etc/dahdi/system.conf>

Pero luego, en el Dialplan tenemos que seguir definiendo en canal a la vieja usanza (DAHDI/1, DAHDI/2, etc…)

Dato importante de las lineas extrantes analogicas, es que hay que mandarlas a un contexto en el DialPlan (por ejemplo, llamadas_entrantes) y dentro de ese contexto, poner la extension “s” (start) ya que es imposible reconocer hacia donde pretende ir esa llamada por las limitaciones de la “analogia”.

Mañana parece que seguiremos con el tema de las conexiones de Tarjeteria, pero esta vez con una nueva que no hemos visto hasta la fecha, una tarjeta de Primarios.

Espero vuestros comentarios sobre como quedo esta “modalidad” de blogging inline. Para mi particularmente resulto mas comoda porque en los huecos libres podia ir escribiendo, y no tener que hacer todo el texto ya a deshoras y ademas tambien ha servido un poco con “apuntes personales” de lo visto para revisiones futuras (como realmente es el blog entero para mi personalmente).

Asterisk Advanced. Day 2

Pasado el primer dia “introductorio” se empiezan a ver conceptos y aplicaciones mas interesantes para nuestro sistema Asterisk. Una de las conclusiones que he sacado en favor del curso, algo que personalmente me suele costar bastante sacar de la mayoria de los cursos que he ido, es que la verdadera utilidad del curso no reside en el material que puedes encontrar en cualquier pagina medianamente buena que trate sobre asterisk como www.voip-info.org, sino realmente en la cantidad de aplicaciones practicas que surgen a raiz de la experiencia del profesor, y tambien de los compañeros del curso.

Realmente Asterisk, exceptuando la idea basica de una centralita, o del concepto generico de “quiero montar un callcenter” o “quiero montar una centralita para mi empresa”, sin ideas practicas de calidad, es totalmente inutil. Pero es cuando las ideas empiezan a ebuillar cuando se pueden empezar a pensar en infinidad de aplicaciones para la vida diaria que pueden resultar extremadamente utiles.

Por eso mas que escribir sobre teoria que se ha visto, y puede consultarse como dije, en VoipInfo, voy a comentar algunas que fueron surgiendo:

– Sistemas de Monitorizacion de llamadas

Seguramente todo buen conocedor de Asterisk (que no es mi caso) sepa, que existen aplicaciones para la grabacion de llamadas. Pero ya que el canal de llamadas puede ser “escuchado” para ser grabado en un fichero de audio, tambien podria ser “escuchado” en tiempo Real. Ahi es donde entran las aplicaciones “Espias” como ExtenSpy y ChanSpy. Dos aplicaciones muy faciles de utilizar en un dialplan:

exten => 100,1,Answer()
exten => 100,n,ChanSpy()
exten => 100,n,Hangup ()

Y simplemente accediendo a la extension 100, tenemos “barra libre” para escuchar todos las conversaciones en el canal SIP de nuestra maquina Asterisk pasando de una a otra desde el telefono a traves del boton “*”

– Generacion de llamadas Automaticas

Por otro lado, algo tambien muy interesante, es la posibilidad de generar llamadas automaticas a traves de un fichero de “llamada” que se introduce en un directorio que esta siendo constantemente “monitorizado” por un demonio de Asterisk que lo ejecuta, y procesa los comandos de la llamada.

Esto por ejemplo puede ser util, a traves de un script autoejecutado en el arranque del sistema, cuyo procedimiento sea, si por ejemplo se cae un servicio critico del servidor, y tenemos instalado un minimo asterisk en ese servidor al que hemos conectado una extension SIP nuestra para alertas, hacemos que cree un fichero de llamada a medida y lo movemos al directorio que comentaba antes ( el directorio exacto es /var/spool/asterisk/outgoing). En este caso, lo que haria seria generar la llamada a nuestra extension alertandonos que el servicio se cayo. Muy practico porque eventualmente todos sabemos que el telefono suele ser de prioridad nivel maxima mientras que el correo electronico (como aplicaciones tipo Nagios que generan y envian correos de alerta), suele ser de prioridad media o medio baja dependiendo el caso. O perfectamente podriamos combinar sistemas como Nagios y Asterisk para diseñar un sistema de alertas mediante mensajes de voz a un telefono provenientes del servidor.

El formato de estos ficheros de llamada es muy sencillo. Un fichero de texto con los posibles siguientes comandos:

Channel: SIP/mi_telefono //El canal a traves del que se cursara la llamada
Application: Playback //Queremos que ejecute la aplicacion Playback para reproducir un mensaje automatico a voluntad
Data: windows-server-caido //El fichero de audio que vamos a lanzar con la aplicacion Playback, en este caso tiene que encontrarse en el correspondiente directorio de sonidos de Asterisk en un formato permitido para su reproduccion por ejemplo windows-server-caido.wav
Codecs: g729, ulaw, gsm // Codecs permitidos por el canal
MaxRetries: 3 // Numero de intentos que se tratara de realizar la accion con exito

– Edicion y personalizacion del Features.conf

Por otro lado, tambien hoy se vio el fichero de configuracion, features.conf, en el que basicamente se definen la utilidad de las pulsaciones de botones DMTF y como seran interpretados por las aplicaciones que conllevan especialmente servicios de llamada como Dial y Queues.

Basicamente ya es sabido que existen en ese fichero una serie de definicios por defecto para realizar “Features” (Caracteristicas) como la transferencia de llamadas, el Parking de llamadas, etc, que quiza comente mas en detalle en un futuro.

Pero siguiendo con la linea practica, un ejemplo que se probo en la clase, fue la posibilidad de crear “Features” a medida, como por ejemplo, mapear dos combinaciones de teclas para subir y bajar el Pitch del canal de audio (para los entendidos en efectos de sonido, es la escala de frecuencia). Esto quiere decir que por ejemplo si tenemos a un operador en la oficina que tiene una voz muy aguda, y queremos dotarle de una voz mas grave sin tener que prescindir de esta persona para llamadas determinadas, le podemos configurar en su telefono la posibilidad de bajar 4 o 5 puntos el nivel de frecuencia, y sonaria tal y como deseamos para el receptor de la llamada. Asunto resuelto, ya tenemos un locutor de radio instantaneo a coste 0.

¿Como se consigue este efecto?

Primero en features.conf bajo el contexto [applicationmap] definimos algo asi:

pitchUp => #1,self/both,Set(PITCH_SHIFT(both)=high)
pitchDown => #2,self/both,Set(PITCH_SHIFT(both)=low)

Con esto decimos que para conseguir alcanzar la caracteristicas “pitchUp” pulsando almohadilla + 1 subimos la frecuencia (tonalidades agudas) y al pulsar # + 2 bajamos la frecuencia (tonalidades graves)

Ahora para que esto sea aplicable a una aplicacion de llamada, es necesario modificar una variable general de Asterisk llamada __DYNAMIC_FEATURES (atencion a las dos _ del comienzo de la variable).

exten => 100,1,Set(__DYNAMIC_FEATURES=pitchUp#pitchDown)
exten => 100,n,Dial(SIP/mitelefono)
exten => 100,n,Hangup()

Ahora al llamar a la extension 100 y contactar con ese canal ahi definido, ambos interlocutores de la conversacion podran manipular su voz pulsando las combinaciones de teclas anteriormente descritas. Todo un lujo de goce y disfrute para la conversacion.

– Importante Novedad de la version 1.8 de Asterisk

Finalmente para terminar, aun a sabiendas que me quedan mil cosas en el tintero que podria escribir, quiero comentar algo nuevo que ha surgido en las ultimas versiones de Asterisk y SIMPLIFICA los Dialplans una burrada.

Hablo de “SAME”. Esto simplamente permite el hecho de poder obviar el exten => junto al numero de extension que vamos repitiendo en un flujo de llamada para una extension concreta

Antes:

exten => _6XX32XZ1X,1,NoOp()
exten =>  _6XX32XZ1X,n,Dial(${Troncal}/${EXTEN})
exten => _6XX32XZ1X,n,Hangup

Ahora:

exten => _6XX32XZ1X,1,NoOp()
same => n,Dial(${Troncal}/${EXTEN})
same => n,Hangup

Definitivamente MUY comodo. Gracias al iluminado por implementar esta mejora.

Eso es todo por hoy, mañana espero, mucho mas.

Asterisk Advanced. Day 1

Primer dia del Asterisk Advanced. Se han visto por lo general temas basicos introductorios del sistema. Todo aquel que hubiera realizado un Fast Start, puede sobrellevar este dia sin despeinarse. Muchos conceptos teoricos sobre Asterisk, curiosidades, producto Digium y alguna terminologia basica en lo referente al protocolo SIP. Nada que merezca por mi parte la pena destacar.

Configurar una extension, un pequeño IVR (como ya hemos visto en anteriores entradas de este blog), y una comunicacion con un proveedor SIP. Me hubiera gustando poder volver a escribir un buen articulo en representacion al dia de hoy, pero no hay suficiente material interesante, que no haya sido visto hasta la fecha.

Solo una cosa tengo que reconocer. Estos meses de inactividad me han hecho olvidar gran parte del sistema de configuracion, y porque no decirlo, esta clase me ha servido para poner un poco al dia mi actividad mental asteriskera, para volver un poco a la carga.

Seguiremos informando!

MeetMe in a Box: Web-MeetMe: Conferencias de Audio de altos vuelos.

Hoy en día es muy común ver multitud de software web, capaz de ofrecer funcionalidades de conferencias online, webminars (seminarios web), y videoconferencias llevadas a reuniones. Llegaremos a eso algún día, pero como para ello se requiere el software, y el hardware especifico (y de calidad), y en estos momentos como todos sabemos, el horno no está para bollos (pese a que la gran mayoría sabemos a día de hoy lo que nos podríamos ahorrar, existen aún defensores, como George Clooney en “Up in the Air” que defienden “lo presencial”).

De momento no vamos a conformarnos con poco, y vamos a tratar de montar un sistemas de conferencias por Audio, de bajo coste, y si puede ser con Teléfonos de por medio, que hoy en día, las llamadas a fijos están muy baratas y dan una calidad de audio ““streaming”” excepcional.

Y a este sistema, Asterisk lo llamó MeetMe. Y realmente es tan simple como el tema de los buzones de voz (incluso más simple aun!) con su Aplicación con el mismo nombre, y su fichero de configuración meetme.conf. Pero voy a dar un paso más allá: Haciendo uso de esta base, poder obtener el potencial de un sistema de Gestión de Conferencias de Audio en tiempo real, a través de una Interfaz Web. Esto, realmente suena mucho mejor que “una conferencia a tres (o a cuatro)”, como quien dice. Vamos allá.

Para la Interfaz Web MeetMe van a hacer falta algunos elementos. Algunos ya los tendremos si hicimos la instalación de LAMP en su día.

En primera instancia vamos a ir descargando el paquete estrella, la interfaz Web-MeetMe. La página oficial seria: https://sourceforge.net/projects/web-meetme/

# tar –xvf web-meetme_(versión que sea)
# cd web-meetme

En primer lugar toca configurar el Driver ODBC para conectar con nuestra base de datos MySQL. Hay que instalar algunos detalles para el ODBC de nuestro sistema
# aptitude install unix-odbc
# aptitude install libmyodbc

Ahora configuramos el driver en condiciones. Primero editamos /etc/odbcinst.ini para crear un driver a MySQL:

[MySQL]
Description = MySQL ODBC MyODBC Driver
Driver = /usr/lib/odbc/libmyodbc.so
Setup = /usr/lib/odbc/libodbcmyS.so

Luego configuramos el fichero /etc/odbc.ini con la siguiente información.

[meetme]
Description = ODBC para MySQL
Driver = MySQL
Server = localhost (local, o servidor donde tengamos la base de datos con el driver ODBC)
Database = meetme (tenemos que crear una base de datos igual que la de Asterisk, pero con este nombre, para diferenciar un poco, en mysql,
Port = 3306
User            = asterisk
Password        = asterisk
Socket = /var/run/mysqld/mysqld.sock (puede que este fichero de socket este en otro sitio dependiendo la distribución donde tenemos nuestro sistema)
Stmt =
Trace = yes
TraceFile = /tmp/odbc.log

No entro en detalles, porque esto es configuración del conector ODBC para acceder a nuestra base de datos MySQL que supuestamente, ya tenemos instalada.

Para configurar la nueva base de datos meetme, simplemente podemos entrar en la consola mysql #mysql –u asterisk –p y poner el comando: CREATE DATABASE `meetme` ;

A partir de ahí generamos las tablas. Si no hemos salido del directorio web-meetme del paquete que descargamos antes ejecutamos:
# mysql –u asterisk –p < ./cbmysql/db-table-create-(version-que-sea).txt
# mysql –u asterisk –p < ./cbmysql/upgrade-db.txt

Ahora realizamos la configuración del conector ODBC de Asterisk, el fichero de configuración es /etc/asterisk/res_odbc.conf, creando un contexto específico para meetme.

[meetme]
dsn => meetme (este es el contexto que creamos antes en el sistema)
username => asterisk (supuestamente va a ser nuestro usuario para asuntos de Asterisk y servidor de base de datos)
password => asterisk (o la que le pusiéramos)
pre-connect => yes

Ahora en extconfig.conf (si tenemos el fichero de ejemplo, tan solo buscamos la línea meetme => y cambiamos lo que haya al completo por:
meetme => odbc,meetme,booking

Como todo lo hacemos a través del driver ODBC pues los Call Detail Records, los vamos a registrar de esta manera también. En el fichero cdr_adaptative_odbc.conf:

[wmm]
connection=meetme
// este es el context que utilizamos antes en res_odbc.conf)
table=cdr
// vamos a llamar a la tabla igual que la llamamos en la bbdd Asterisk. Realmente podríamos basarnos en la misma base de datos que ya tenemos, pero en este caso, para que no sea estrictamente necesario seguir el planteamiento de CDR-Stats vamos a independizarlo.

También hace falta introducir una pequeña opción en meetme.conf para evitar usar una columna del Asterisk RealTime para meetme que web-meetme no utiliza:

logmembercount=no

Después de esto tenemos una opción para acceder al sistema utilizando un servicio LDAP, o utilizando usuarios creados a mano en la base de datos. En nuestro caso de momento, vamos con esta opción, ya que a priori tampoco deberíamos tener tantos… o sí. Me apunto esto para en un futuro, actualizar con un sistema LDAP como ampliación del poder de Asterisk + LINUX. Para crear la estructura de la tabla “user”, como antes en el directorio web-meetme ejecutamos:
# mysql –u asterisk –p < ./cbmysql/db-admin-user-create.txt

Con esto ya tenemos creada la base del sistema.

Ahora vamos a configurar el sistema Web-Meetme en si.

En primer lugar tenemos que preparar la interfaz web dentro de nuestro directorio raíz donde se publican las web de nuestro servidor Apache. Por regla general y por defecto suele ser /var/www. Ahí podemos crear un nuevo directorio específico para Web-Meetme
#mkdir /var/www/web-meetme

Ahora vamos a copiar todo el tarball que descargamos al principio de Web-Meetme en este directorio recién creado:

#cp –r /ruta/donde/este/nuestro/tarball/descomprimido /var/www/web-meetme

Ahora toca configurar los parámetros de nuestra Interfaz Web en los ficheros de configuración de la misma, en primer lugar dentro del directorio raíz de web-meetme vamos /lib/defines.php de momento lo básico es configurar los datos de acceso a nuestra base de datos y algunos campos clave:

define (“WEBROOT”, “http://ip-nuestro-servidor/web-meetme/”);
// La dirección web relativa de nuestro
define (“FSROOT”, “/var/www/web-meetme/”);
// La ruta a la interfaz
define (“LIBDIR”, FSROOT.”lib/”);
// Esto tal cual

Finalmente editamos una más, para identificación de usuarios, en nuestro caso habíamos creado una tabla “user” (automáticamente durante el proceso de carga de datos SQL que hicimos antes) dentro de nuestra base de datos meetme para la administración de usuarios:

define (“AUTH_TYPE”, “sqldb”); // adLDAP or sqldb

Existe un usuario en la base de datos administrador creado por defecto. Que luego usaremos para acceder el sistema y poder crear usuarios adicionales personalizados.
Usuario: wmm@localhost
Password: wmmpw

También es necesario configurar los parámetros de la base de datos. En este caso se realiza desde el fichero dentro de /lib/database.php:

$database = ‘meetme’;
$host = ‘localhost’;
$username = ‘asterisk’;
$password = ‘asterisk’;

Si os fijáis este fichero hace referencia a un módulo DB.php. Para poder hacer uso de este también es necesario instalar un paquete, php-pear y su módulo db
# aptitude install php-pear
# pear install db
El caso es que al parecer el modulo db ha quedado obsoleto y lo sustituye mdb2
# pear install mdb2 (aunque con el primero ya es suficiente en el momento que escribo este artículo)

Por otro lado nos toca configurar la interfaz para comunicarse con el Asterisk Manager. Para ello debemos configurar primero el manager de Asterisk y añadir un usuario para esto específico. En el directorio /etc/asterisk, fichero manager.conf, creamos un nuevo contexto, que va a ser justamente el usuario que vamos a utilizar:

[meetme]
secret = meetme (la password que queramos)
read = call
write = command,originate
Y luego como siempre #asterisk –rx ‘manager reload’

Y ahora en el directorio de la interfaz web de Web-Meetme, dentro de /phpagi tenemos un fichero de configuración de ejemplo que vamos a utilizar
#cd /var/www/web-meetme/phpagi
#cp phpagi.example.conf /etc/asterisk/phpagi.conf

Y lo editamos asi:
# vim /etc/asterisk/phpagi.conf

Dentro de [asmanager]
server=localhost
port=5038
username=meetme
secret=meetme

También tenemos que editar el fichero index.html para adaptarlo a la ruta relativa de nuestra web. Algo así:

<META HTTP-EQUIV=”REFRESH” CONTENT=”0; URL=http://servidor_ip/web-meetme/meetme_control.php”>

Y ya está todo lo básico. Ahora podemos acceder a nuestro sistema Web MeetMe desde
http://ip_servidor/web-meetme

Lo último de todo sería configurar una marcación en el extensions.conf para poder acceder a nuestro sistema, sea desde un DID que tuviéramos configurado, o directamente a la extensión en concreto. Por ejemplo:

exten => 5000,1,NoOp()
exten => 5000,n,Answer
exten => 5000,n,MeetMe()

Y con esto marcando el 5000 si en la interfaz habíamos creado un número de conferencia, nos pedirá, el número de conferencia y el PIN asignado para acceder a la misma.

Lo más curioso de esto es que en este proyecto también está presente Areski Belaid, creador del CDR-Stats y también de A2Billing, uno de  “tarificadores” más reconocidos en Asterisk, y desde este Blog agradecemos sus contribuciones al mundo de la Interfaz web para Asterisk.

Otras curiosidades que he encontrado, php-agi no está diseñado para trabajar con una version PHP superior a 5.2. Es por esto por lo que aparece un error en el log de apache constante:

PHP Parse error:  syntax error, unexpected T_GOTO, expecting T_STRING

La solución a este problema es muy fácil, la function goto está obsoleta, por eso vamos a nuestro directorio de web-meetme /var/www/web-meetme/phpagi y dentro modificamos el fichero phpagi.php, vamos a la línea donde aparece:

“function goto”

Y la cambiamos por “function goto2”. Así de simple.

Así el sistema quedaría configurado como para poder crear una sala de conferencias, visualizar los usuarios, expulsarlos a voluntad, bloquearles el micrófono, gestiones simples de administración de conferencias… aunque todavía no he llegado a alcanzar el 100% de la funcionalidad. La documentación es muy pobre, y mis vanos intentos de conseguir resultados no han llegado a buen puerto. Por ejemplo la función de Invite, para poder ser aplicada a través de un Troncal SIP, no consigo hacer que el sistema se autentifique correctamente para lanzar la llamada a través del mismo. La mayor parte de la configuración se consigue editando las variables del fichero defines.php, aun así, he de reconocer que el software tiene un nivel de personalización bastante grande, ya entrare en detalles sobre esto en otro momento. Al menos con esto es posible tener en marcha lo básico para poder trabajar eficientemente.

Conquistando el Dialplan II: Configuración DID para Operadores IP

Para todos aquellos que utilizamos operadores SIP tenemos la gran posibilidad de adquirir múltiples canales entrantes a muy bajo coste. A día de hoy la verdad que las llamadas salientes salen realmente caras, sobre todo si nos vemos en entornos empresariales. Ya hace tiempo os comente múltiples alternativas que había barajado en su día, con operadores como Netelip, Voztelecom, Telsome. A día de hoy, 2 céntimos el minuto para llamadas nacionales: Es muy caro. Tenemos alternativas internacionales como CheapVoip, pero aquí entra en juego el tema de las latencias. Además estas no nos ofrecen líneas de entrada y/o DID por tanto no podemos adquirir un sistema integral de llamadas tanto de entrada como de salida.

Aquellas empresas que si ofrecen canales de entrada, “se aprovechan” a un alto coste para la salida. Podemos combinar ambas soluciones, y de hecho, debemos, pero ya en estos casos las líneas de entrada empiezan a compensar cada vez menos.

Aun así, para configuraciones de pocas líneas de entrada (menos de 10) y relativamente pocos DID, (menos de 50), siguen siendo soluciones factibles. Por ejemplo una de las soluciones más óptimas en el mercado español, VozTelecom, con líneas de calidad muy muy alta a nivel de latencia, jitter, etc., ofrece por 8 euros, 2 canales de entrada, y 1 DID, 4 euros el DID adicional geográfico. Encima, los temas técnicos los libramos, y no tenemos que contratar mantenimientos adicionales para preservar la calidad del servicio

Si optamos la opción de Telefónica, tenemos una línea RDSI por 29 euros al mes, más el mantenimiento, habría que sumarle, mínimo, 4 euros para preservar una calidad aceptable de respuesta. Esto hace 33 euros. Luego los DID son relativamente baratos, en torno a los 2 euros.

Si no queremos optar por la opción del primario, 4 RDSI haciendo un grupo ISPBX (para saltos automáticos y demás), sumaria un total de 132 euros. En caso de VozTelecom hablaríamos de 32 euros. Luego si queremos 30 DID, serian 60 euros más para Telefónica 192 euros, y 120 euros para Voz Telecom: 152 euros. Solo 45 euros, estamos en el umbral. Aunque obviamente la solución con líneas RDSI es muy superior a la solución VOIP, porque además que podríamos “aislar” el sistema PBX a un nivel puramente local, si requerir de Internet, la calidad siempre suele ser superior a nivel de voz. Solo con un Gateway Epygi como el que vimos antes, tendríamos resuelta la papeleta.

Vamos a poner el caso concreto, de que elijamos la solución VoIP. Ahí vamos con la configuración:

En caso del Epygi, realmente no necesitamos un comando “register” en el fichero sip.conf para registrarnos contra el troncal. Pero en caso del operador SIP, si haría falta, como vimos con anterioridad. Esto nos “obliga” a ir hacia la extensión del Dialplan dentro del contexto que seleccionemos específicamente.

Y desde esa extensión, tendremos que realizar la configuración para seleccionar el DID que “recibamos” según los mensajes SIP que se intercambian durante la comunicación. Esto ocurre con la mayoría de los operadores IP, aunque algunos ejercen de troncal de forma equivalente al Epygi, que no necesitaremos realizar selección alguna:

En el extensions.conf imaginando que si pusimos contexto destino, en la configuración del operador SIP, pero no pusimos extensión destino en el comando Register (último parámetro /ddi como vimos antes):

exten => s,1,NoOp()
exten => s,n,Set(cNum=${SIP_HEADER(TO):5:9})
exten => s,n,GotoIf($[“${cNum}” = “987654321”]?1,1)
exten => s,n,GotoIf($[“${cNum}” = “912345678”]?2,1)
exten => s,n,GotoIf($[“${cNum}” = “988776655”]?3,1)
exten => s,n,Hangup()

Con la variable general SIP_HEADER, seleccionamos la cabecera del mensaje SIP, y nos vamos a la posición 5 longitud 9 (el número de teléfono) para guardarlo en una variable local que le llamamos cNum. Aquí en 99% de los casos se encuentra el DID. De todas formas haciendo debug en la consola (# asterisk –r) podemos ver exactamente qué valor está recibiendo esta variable, cNum

Esta sintaxis es nueva para nosotros. La aplicación GotoIf es condicional. Con el formato GotoIf($[condición], se cumple, no se cumple), En este caso concreto, si se cumple, saltamos al contexto 1, 2 o 3 según lo que se cumpla, y si no se cumple, pasamos a la siguiente prioridad.

La consulta de variables en Asterisk tiene el formato ${variable} en cambio la “escritura” de las mismas con la aplicación Set, se realiza sin nada, variable=. Esto es un poco técnico, aun con ciertos conocimientos de programación, esto se aprende en cuestión de segundos.

Así en vez de ir discriminando con extensiones con el número DID como hacíamos con el Epygi, lo haremos con este sistema por condicionales. Lo que no tengo muy claro todavía es porque algunos operadores mandan bien (y sin entender a qué me refiero con “mandar bien” el DID para asignarlo directamente como extensión), y para otros, hay que hacer operaciones como estas para salir al paso. Si lo averiguo, actualizare este mensaje.

Para finalizar con todo esto, voy a aprovechar, para hacer un apunte fuera del contexto. El tema es que Asterisk, por ventaja, o desgracia, favorece mucho a los informáticos, y acerca un mundo anteriormente exclusivo a ciertos técnicos especializados, o especialistas de las telecomunicaciones, al mundo de los informáticos. Por esto si realmente no tenemos nociones extensivas tanto de Linux como de programación, nos vamos a ver con un sistema bastante simple, (aun aceptable comparativamente con otras soluciones PBX), pero no vamos a poder sacar toda la potencia de su interior al máximo. No voy a pararme demasiado en temas de programación, variables, condicionales, bucles, aunque si explicando el formato, porque doy por supuesto que más o menos entendemos de que estoy hablando, y más considerando que desde hoy, la curva de aprendizaje va mejorando para el público entendido en esta materia, pero va a empeorar drásticamente para los que carezcan de estos conocimientos.

Conquistando el Dialplan I. Aplicaciones Asterisk: Voicemail

Como ya sabemos, el Dialplan, plan de marcación, es el esqueleto en esencia de Asterisk. A partir de este se abre el sin fin de posibilidades que nos ofrece este sistema.

Solo el que conoce lo que ofrece el Dialplan al 100%, es aquel que realmente conoce Asterisk de verdad. Por ello, las series de documentación sobre Dialplan serán mensajes mas cortitos pero no por ello menos interesantes  y que ayudaran a organizar mejor la información.

Realmente ya vimos parte del potencial del Dialplan, con la creación de una operadora automática de coste cero, ahora vamos a ver las funciones de Buzón de Voz para nuestras extensiones. Aquí básicamente hay dos actores principales. La Aplicación Voicemail, y el fichero voicemail.conf

El fichero voicemail.conf puede llegar a ser todo lo complejo que deseemos en función de nuestras necesidades, pero voy a comentar un caso práctico en el que podemos ver diversa funcionalidad que podemos llegar alcanzar. Como la mayoría de los ficheros de Asterisk, se divide en contextos, como casi siempre, general, suele ser el genérico que afecta a todos los contextos por igual.

[general]
format=wav
//Formato de las grabaciones para el buzon de voz. Se admiten otros formatos como gsm.
serveremail=direccion@queenvia.com
//Direccion del remitente de los envios
attach=yes
// Para enviar el fichero adjunto en los emails con el audio
delete=yes
// Para permitir la opción de borrado del mensaje de voz local en el servidor una vez enviado por correo eletronico
maxmsg=100
// Maximo numero de mensajes permitidos en la bandeja local por buzon
maxsecs=180
// Maximos segundos por mensaje
minsecs=2
// Minimos segundos por mensaje para desechar los mensajes vacios o casi vacios
skipms=3000
// Opciones del mensaje de audio, para indexarlo cara a desplazamientos X ms adelante o detrás cuando sea reproducido en el pc del destinatario
maxsilence=10

// Silencio máximo permitido, esto es importante cara a poder desconectar la llamada en caso de silencio antes de cumplir el máximo posible caso 180 segundos (en nuestro ejemplo)
silencethreshold=128
// Este es el umbral de audio para el que consideramos que es un silencio, de aquí podemos ir mas abajo o mas arriba en función de nuestra necesidad, no hay un valor “ideal”
maxlogins=3
// Intentos de acceso a voicemail, en caso de sobrepasarlos, Asterisk desconectara al usuario de su cuenta SIP/IAX
emailsubject=Nuevo Mensaje de ${VM_CALLERID}
emailbody=Buenos días ${VM_NAME},\n\nHemos recibido un mensaje en su buzon de voz…
// Esto seria el asunto y el cuerpo del mensaje email. Aquí se pueden aprovechar variables para poder formatear el correo y mostrar datos quizá interesantes para el destinatario. Algunas de estas variables de ejemplo:
${VM_CALLERID}: El numero identificador del llamante (el número de teléfono)
${VM_NAME}: El nombre del dueño del buzon (lo definiremos más adelante)
${VM_DUR}: Duracion del mensaje
${VM_DATE}: Fecha y hora de recogida del mensaje
Mas variables pueden encontrarse aquí: en su correspondiente sección (tampoco son muchas más)
emaildateformat=%A, %B %d, %Y at %r
// Formato de la fecha para el email. Para la variable VM_DATE. Consultar el manual de date para mas información (# man date)

Con esto tenemos más que suficiente para componer mensajes para el buzon de voz y enviarlos por email. Ahora vienen los contextos. Como siempre, si es [default] es el genérico, y luego los contextos específicos. En principio vamos a poner uno genérico y uno especifico.
[default]
1234 => 5678,Buzon de Ejemplo,ejemplo@buzones.com
– En primer lugar, el número del buzón, luego lo utilizaremos en el Dialplan para la aplicación Voicemail así referirnos a este buzón
– En segundo lugar, la contraseña para acceder al buzón. Tendremos que crear una “extensión” en el Dialplan para que el usuario pueda acceder a su buzón de forma interna. Esto solo es útil si no marcamos la opción de borrado de mensajes del buzón al ser enviados por email
– En tercer lugar, nombre del buzón que luego utilizaremos en variables como VM_NAME
– En cuarto lugar, Email del destinatario de los mensajes de este buzón

Este es un ejemplo muy sencillo, pero a esto podríamos aplicarle un poco mas de complejidad al asunto

[extensiones]
1000 => 9878,Mr. Lenny, lenny@debian.net,,attach=yes|delete=1
– En quinto lugar, iria la dirección del Pager… muy poco utilizado a dia de hoy
– En último lugar, irían opciones especiales. En este caso, decimos que adjunto el mensaje, y lo borre a continuación. Si hemos activado las opciones en el contexto general, ira bien esto.

Si queremos hacer “broadcasting” de mensajes de buzon a varios emails, hay varios métodos pero el que a mi mejor me ha funcionado es hacerlo en combinación a aliases del servidor de correo (en nuestro caso al usar Ubuntu, por defecto, Postfix)

1001 => 8765, Dpto. de Botijos, botijos@nuestroservidor,,attach=yes|delete=1

Nos vamos a /etc/aliases y añadimos
botijos: sr.sanchez@botijoland.com,sr.perez@botijoland.com,sr.alvarez@botijoland.com

Y refrescamos aliases comando: # newaliases

Por ultimo no olvidemos recargar nuestro voicemail.conf #asterisk –rx ‘voicemail reload’

Ahora toca editar nuestro Dialplan para poder utilizar estos buzones recién configurados. Vamos al extensions.conf:

Si queremos por ejemplo hacer que los usuarios puedan dejar mensajes a nuestro contestador tenemos que utilizar la aplicación Voicemail
Ejemplo:

exten => 1000,1,NoOp()
exten => 1000,n,Dial(SIP/1000,30)
exten => 1000,n,Voicemail(1000@extensiones,u)
// En este caso, ponemos el número del buzón que pusimos antes @ el contexto al que pertenecía, adicionalmente ponemos una opción, para que antes de dar el pitido de “empezar a grabar” diga el mensaje de “en estos momentos no nos encontramos, deje su mensaje después de oír la señal”. Aquí tenemos varias, opciones, en vez de utilizar los mensajes por defecto que se pueden encontrar en la carpeta de sonidos /var/lib/asterisk/sounds/ todos los que empiezan por vm- tienen algo que ver con el buzón de voz y estas opciones. Las opciones posibles son:
sin opciones: se escuchan las instrucciones para dejar el mensaje
s: no se escucha nada (útil si queremos poner mensajes personalizados para cada usuario)
su: mensaje de no disponible
u: mensaje de no disponible + instrucciones
sb: mensaje de ocupado
b: mensaje de ocupado + instrucciones

Con esto también podemos jugar con las aplicaciones Playback y Record, para con la opción “s” crear un buzón acorde a las necesidades de un usuario en concreto

Por otro lado vendría la aplicación destinada a escuchar los mensajes guardados si no pusimos la opción de borrado automático: VoicemailMain. Tiene poca historia:
exten => 10001,1,VoicemailMain(1000@extensiones)
El tema es que a partir de ahí vendría un menú relativamente complejo, editable, y demás. Yo personalmente no lo utilizo ya que la función de envío a correo aparte de que me descarga el disco duro, hoy en día a la mayoría del personal le resulta formidable. Aun así, para aquellos que deseen profundizar, les dejo un enlace al manual por si acaso quieren probarlo. Cualquier consulta acerca de esto, no duden en comentármela!

En principio, con todo esto, ya se podrían componer sistemas de Buzón de voz bastante interesantes. Como ven no es demasiado complejo y existen muchas alternativas y opciones. Yo personalmente opino que las opciones de envío a correo, todavía están muy poco elaboradas, pese a que se ha profundizado en ellas. Yo personalmente no he encontrado opciones por ejemplo, de envío CC o CCO (BCC) para envíos broadcasting (lo cual me resultaría muy interesante). Supongo que sería una cuestión de apoyar programando, al proyecto Asterisk. Quien sabe, a lo mejor más adelante nos animamos a ello.

Preparando nuestro sistema de FAX en Asterisk: Hylafax + IAXModem

Hoy voy a tratar de explicar cómo crear un sistema de faxing a través de nuestro Gateway (o tarjeta) para poder recibir faxes a email, y poder enviar faxes con un software desde nuestros PCs. He observado múltiples manuales en la web, pero la verdad es que si no tienes “suerte” encontraras miles de problemas, especialmente en las últimas versiones de Ubuntu Server. Y la verdad es que cuantos más problemas mejor, así aprendemos más sobre el asunto que nos concierne.

En primer lugar toca configurar nuestro IAX.conf para añadir una extensión para el FAX

[iaxmodem]
type=friend
username=iaxmodem
//secret=contraseña_de_la_extension
secret=fax
qualify=yes
notransfer=yes
disallow=all
allow=ulaw
host=dynamic
context=extensions
callerid=”FAX” <100>
requirecalltoken=no
// esta línea ultima es muy importante rebaja la seguridad de IAX para esta extensión, pero sino lo ponemos no funcionara IAXmodem en concreto

Acto seguido vamos a configurar nuestro Dialplan para a través de un número DID que tenemos disponible o línea analógica conectada (como hemos visto en anteriores mensajes, configuraciones relacionadas al Gateway RDSI, o relacionadas al módulo DAHDI desde chan_dahdi.conf), indiquemos a que extensión se deben enviar los FAXes (en este caso IAX2/iaxmodem) que es nuestra extensión IAX para el FAX. Esto se añadiría en el contexto que se envían las llamadas de nuestra PSTN (en nuestro caso desde-isdn)

exten => 123123123,1,NoOp()
exten => 123123123,n,Answer()
exten => 123123123,n,Wait(3)
exten => 123123123,n,Dial(IAX2/iaxmodem)

Quiero recordar que cuando hagamos modificaciones en los ficheros es necesario “Recargar” nuestro asterisk para que tome los cambios. No estoy seguro en este punto, si ni siquiera lo comente alguna vez!

# asterisk –x dialplan reload
# asterisk –x iax2 reload

(Recargamos el extensions .conf modificado y el iax.conf modificado)

Ahora toca configurar un modem capaz de reconocer los “tonos” de los faxes, a través de nuestra extensión IAX recién creada. Todo a través de software. La aplicación en cuestión, se llama IAXmodem

Podemos descargarla desde aquí:  http://sourceforge.net/projects/iaxmodem/files/iaxmodem/

Ahora la descomprimimos:

# tar –xvf iaxmodem-versionquesea.tar.gz
# cd iaxmodem-versionquesea
Necesitamos alguna librería adicional en nuestro sistema para poder compilar:

# aptitude install libtiff-dev libtiff-tools
# ./configure
# make

Con esto creamos el binario iaxmodem. Lo copiamos en el path de ejecución de binarios, generalmente /usr/bin o /usr/local/bin o /usr/local/sbin

# cp iaxmodem /usr/local/bin

Y ahora nos toca configurar un puerto virtual para que iaxmodem sea capaz de generar la señal, tendriamos que crear el archivo /etc/iaxmodem/ttyIAX con la siguiente información:

device /dev/ttyIAX
owner asterisk:asterisk
mode 660
port 4570
refresh 300
server 127.0.0.1
peername iaxmodem
secret fax
cidname FAXIAX
cidnumber 100
codec ulaw

Es muy importante asignar un Puerto diferente al de IAX (4569) para que funcione puesto que esta extensión estará siempre en activo como veremos ahora. Sería necesario configurar un script de arranque event.d para que esto ocurra. Dentro de /etc/init/
#vim /etc/init/iaxmodem.conf

start on startup
respawn
exec /usr/local/bin/iaxmodem ttyIAX

Probamos para ver si hemos configurado bien iaxmodem:
# iaxmodem ttyIAX
Si aparece: Registration completed successfully.
Entonces hemos tenido éxito en la configuración.

Después arrancamos el “servicio” con el comando:
# start iaxmodem

ATENCION: Este sistema de scripting es el sistema por defecto de las últimas versiones de Ubuntu, concretamente es Upstart, para más información: http://upstart.ubuntu.com/getting-started.html.  Anteriormente esto se hacia dentro /etc/event.d  en versiones anteriores a la 9.10 e incluso antes esto se hacía en inittab, clásico de sistemas Debian. Parece que se mantendrá ahora así, pero como Ubuntu va cambiando constantemente, obliga a tenernos actualizados constantemente, y por tanto esto está sujeto a modificaciones.  Si no os arranca automáticamente, investigad un poquito, o mandadme un comentario a ver si os pudiera ayudar y/o actualizar este mensaje.

Ahora viene la instalación de Hylafax para manejar los FAXes que entren por este modem.

Primero descargamos las fuentes:
# wget ftp://ftp.hylafax.org/source/hylafax-6.0.5.tar.gz
# tar –xvf hylafax-versionquesea.tar.gz
# cd hylafax-versionquesea

Y compilamos como casi siempre

# ./configure
Aquí nos muestra  los directorios donde se encuentran aplicaciones básicas, decimos que si a todo si estamos conformes (que creo que lo estaremos casi siempre)
# make
# make install

Ahora necesitamos que faxgetty (para recibir faxes) funcione automáticamente como hicimos antes con iaxmodem. Lo mismo, introducimos el fichero de configuración en /etc/init:

# nano /etc/init/ttyIAX.conf
start on startup
respawn
exec /usr/local/sbin/faxgetty ttyIAX

Y arrancamos con start ttyIAX igual que antes. Ahora tocaría configurar un poco el sistema de fax con faxsetup. En general todas las opciones por defecto, pero hay ciertas preguntas que debemos responder para mejorar la fiabilidad del sistema:
Serial port that modem is connected to []?
Ponemos ttyIAX que es nuestro iaxmodem

También configuramos parámetros de número de fax y demás, no es que sea crucial pero cara al envío es importante puesto que en las cabeceras de los FAX esto es lo que aparece.

Otra pregunta importante:
Rings to wait before answering [1]?
Ponemos “2” para asegurarnos que pasa un poco antes de empezar a recepcionar el FAX. No es fundamental, pero ayuda a que fallen menos Faxes por experiencia.

Seguimos adelante hasta que nos pida configurar otro modem y decimos que no para terminar: Do you want to run faxaddmodem to configure another modem [yes]?

Ahora vamos a probar que todo quedo bien configurado. Llamemos al teléfono que hemos configurado el FAX 123123123. Y si todo fue bien, oiremos los típicos pitidos de FAX.

Por defecto, todos los faxes van a parar a /var/spool/hylafax/recvq en formato TIFF.

Si queremos que el FAX recibido se envíe automáticamente, adjuntando la imagen TIFF en formato PDF, y utilizando una plantilla de envío en Español, tenemos que editar un fichero dentro de /var/spool/hylafax/etc/FaxDispatch y añadimos:

TEMPLATE=es;
FILETYPE=pdf;
NOTIFY_FAXMASTER=errors;
FROMADDR=email.que@envia.com
case “$DEVICE” in
ttyIAX)
TOADDR=email.que@recibe.com;SENDTO=email.que@recibe.com;;
esac

Si fallara por cualquier razón, estaría bien que pusiéramos un email de administrador. En /etc/aliases hay que incluir la línea
FaxMaster: nuestroemail@de.administrador

Y “refrescar” los aliases: # newaliases

Es importante respetar los ‘;’ y sin espacios donde no tiene que haberlos. Considerar que es importante definir un FROMADDR exclusivamente, cuando utilicemos un Smarthost en nuestro servidor de correo que requiera autenticación, ya que por defecto se enviara el correo con el usuario “fax”. Todos los parámetros por defecto que no incluyamos en este fichero los recogerá de /var/spool/hylafax/bin/faxrcvd

Si teníamos la ruta de uuencode en setup.cache funcionara correctamente. Básicamente las instrucciones estas pueden encontrarse aquí

Ahora viene la parte, para enviar un FAX, tenemos múltiples opciones. Vamos a considerar en principio que nos encontramos ante una red común en Windows, con máquinas Windows XP.  Existe un software que carga un puerto de impresión para poder enviar Faxes como si de una impresión se tratase por una “impresora” virtual sobre este puerto. De este tipo hay varias opciones, pero la que vamos a tratar aquí de ejemplo es Winprint Hylafax.

La página oficial de descarga es: http://winprinthylafax.sourceforge.net/

ACTUALIZACION: Ya existe version de Winprint Hylafax para Windows 7!: http://sourceforge.net/projects/wphfforwin7/files/

Y sobran las explicaciones de configuración, ya que en la propia página aparece un pequeño manual con capturas de pantalla. Pero este manual solo explica como configurar la interfaz en Windows. Por otro lado tenemos que tomar algunas consideraciones para hacerlo funcionar.

Por un lado tenemos el fichero de configuración de “hosts” permitidos, usuarios y contraseñas. Se encuentra en /var/spool/hylafax/etc/hosts.hfaxd. El formato para registrar nuevos se puede consultar en la página de manual de este fichero man hosts.hfaxd

Básicamente se trata de una expresión regular bien explicada, en la que introduciremos la red, para la cual será permitido enviar FAXes con este software. Ejemplo:

localhost
127.0.0.1
fax@10.158.[0-9]+.[0-9]+::
// Con esta línea sería equivalente a dar permiso a todos los equipos de la subred 192.168.1.0/24, además en la última pantalla de configuración, estaremos obligados a poner un usuario “fax” pero no necesariamente una contraseña.

Lo más importante es especificar en la primera línea de la pantalla de configuración, el servidor Asterisk. Aparte sería interesante especificar el modem que vamos a utilizar para enviar (en nuestro caso ttyIAX)

Tenemos otras opciones como Default Notify, que sería el correo de confirmación de entrega o error, también Address Book Format (dos ficheros o un fichero CSV para almacenar nuestra libreta de direcciones) y la ruta de nuestro ordenador donde queremos guardar la libreta (ejemplo C:\libreta), y finalmente parámetros de calidad y tipo de papel.

Con esto, al imprimir una hoja por esta impresora, nos pedirá los datos de envío y procederemos con el mismo

Por último, si queremos que las notificaciones lleguen en español necesitamos crear un fichero dentro de /var/spool/hylafax/etc/FaxNotify y añadimos:
TEMPLATE=es;
Muy parecido a lo que hicimos en el FaxDispatch

Voy a comentar un aspecto que puede ser interesante para muchos, ya que el envío de FAX y la recepción suele traer muchos quebraderos de cabeza. Las líneas RDSI, primarios, y líneas analógicas, es decir, el mundo PSTN es realmente la única vía aceptable para poder manejar la señal de FAX sin grandes complejidades. El envío a través de proveedores SIP, o a través de enlaces GSM puede dar lugar a problemas y errores que son bastante difíciles de solucionar, y yo personalmente aún no he conseguido aliviar, aunque la verdad es que resultaría bastante interesante profundizar sobre este tema.

Concretamente si leísteis mensajes anteriores, veréis como todas las salidas de mi central de pruebas son a través de enlaces GSM. Esto quiere decir, que he tenido que hacer modificaciones específicas en el Gateway Epygi, y en el Dialplan, para poder enviar Faxes específicamente, por las líneas RDSI que a priori, iban a estar exclusivamente dedicadas para la recepción de llamadas.

Para ello aquí van las dos modificaciones de ejemplo que tuve que hacer:

1.       Por un lado en el extensions.conf, cree una regla adicional sobre la que ya había, para salida al exterior:

exten => _3[9]ZXXXXXXX,1,NoOp()

exten => _3[9]ZXXXXXXX,n,Dial(SIP/${EXTEN}@my-isdn,30)

exten => _3[9]ZXXXXXXX,n,Hangup()

Con esto estoy diciendo, que para mandar un fax, primero hay que marcar el número 3. Así le mandaremos al Epygi un número del tipo “3987654321”

2.       Ahora en el Epygi, como vimos, en Call Routing -> Call Routing Table vamos a crear una ruta equivalente a las otras dos que hicimos, pero saliendo por uno de os troncales donde teníamos conectado una línea ISDN (en nuestro caso por ejemplo, el troncal 2). La única diferencia es que en la primera parte de la configuración pondríamos:
Enable Record activado
Tipo de llamada, ISDN
Pattern: 3* (para que sean todas las llamadas que empiecen por 3, es decir las que vienen para FAXes)
Number of Discarded Symbols: 1 (para que descarte el primer símbolo, el 3, a la hora de hacer la llamada a través del ISDN)

Description: isdn fax (aquí ponemos lo que queremos, yo pongo isdn 1 para saber que troncal de fax)

El resto, todo igual que los otros que ya configuramos. Incluso podríamos hacer otra línea equivalente, con razón de Failover igual, para tener la opción de ocupar múltiples troncales RDSI en caso que los otros estuvieran ocupados.

Si quisiéramos enviar un FAX de prueba utilizaríamos la herramienta sendfax con el siguiente comando:

$ sendfax -n -d 33987654321 /etc/issue.net
// Enviaríamos la información de /etc/issue.net simbólicamente

Seguramente recibamos un error con la métrica de fuentes Courier Bold. Necesitamos  instalar las fuentes ghostscript para ello podemos descargarlas y descomprimirlas en el directorio /usr/local/lib/ghostscript/fonts que es el que por defecto utiliza Hylafax para estas fuentes (sino existe podemos crearlo)
# mkdir /usr/local/lib/ghostscript/
# cd /usr/local/lib/ghostscript/
# wget http://ghostscript.googlecode.com/files/ghostscript-fonts-std-8.11.tar.gz
# tar –xvf ghostscript-fonts-std-8.11.tar.gz

¿Qué ocurriría si deseáramos auto enviarnos faxes con motivo de pruebas? Al enviar a través de la extensión iaxmodem, daría comunicando. Como es gratis tener múltiples instancias de iaxmodem (aunque no sean gratis los canales subyacentes a estas instancias, damos por supuesto que nos sobran para este supuesto), pues vamos a ello (aunque también se podría hacer que la extensión IAX fuese capaz de recibir y enviar múltiples llamadas sin dar comunicando, pero yo no lo he conseguido aun, quizá exista un parámetro para el contexto en el iax.conf que desconozco).

En primer lugar debemos crearnos otro modem IAX como vimos antes, otra extensión IAX. De momento para simplificar el iax.conf vamos a crear una máscara basándonos en el contexto [iaxmodem] que creamos antes. Cambiamos [iaxmodem] por [modem] y le añadimos (!)

[modem](!)
//con los mismos parámetros que antes, sacamos username, secret y callerid
[iaxmodem](modems)
// y aquí ponemos esos tres parámetros específicos del modem primero que creamos
[iaxmodem2](modems)
// Lo mismo que para iaxmodem pero nuevos parámetros
username=iaxmodem2
secret=fax
callerid=”Fax 2″ <101>

Luego copiamos el ttyIAX y lo modificamos el nuevo ttyIAX2
# cd /etc/iaxmodem/ttyIAX
# cp ttyIAX ttyIAX2

Ejemplo:
device /dev/ttyIAX2
owner asterisk:asterisk
mode 660
port 4571
refresh 300
server 127.0.0.1
peername iaxmodem2
secret faxiax
cidname iaxFAX 2
cidnumber 101
codec ulaw

Y lo probamos # iaxmodem ttyIAX2 y creamos el archivo para autoejecucion en /etc/init y demás:

#  cp/etc/init/iaxmodem.conf /etc/init/iaxmodem2.conf
Editamos el iaxmodem2.conf y cambiamos el final por iaxmodem ttyIAX2
# start iaxmodem2

Necesitamos configurar también Hylafax para la gestión de envío de estos faxes, para ello copiamos el archivo de configuración del otro modem. Realmente no necesitamos editar nada relacionado a faxgetty puesto que no tendríamos, al menos en este caso, recibir faxes por este canal de fax.

#cd /var/spool/hylafax/etc/
#cp config.ttyIAX config.ttyIAX2

Y finalmente # faxaddmodem ttyIAX2 y dejamos todos los parámetros por defecto tal cual se nos presentan. Para inicializarlo # faxmodem ttyIAX2. Podemos crear un script como el de faxgetty que creamos antes para la recepción de faxes equivalente. En /etc/init creamos el fichero ttyIAX2.conf con:

start on startup
respawn
exec /usr/local/sbin/faxgetty ttyIAX2

Realmente faxgetty es el único comando que funciona a modo “demonio” y sirve tanto para hacer que el modem IAX pueda tanto recibir como enviar. En este caso vamos a usar ttyIAX2 para enviar pero igualmente podría recibir.

Si pusiéramos en consola #faxmodem ttyIAX2, también resultaría para enviar, pero este comando no funciona para ser utilizando para dejarlo en background como demonio. Si alguien conoce alguna forma de conseguir este mismo efecto sin ponerlo en escucha con faxgetty actualizaría este mensaje con la novedad.

Y ahora por fin si:
$ sendfax -n -d 3987654321 -h ttyIAX2@localhost /etc/issue.net

Y finalmente recibiremos nuestro propio FAX como corresponde comprobando que todo está correcto y funcionando.

Debo decir que realmente esto se podría haber resumido bastante si hubiéramos utilizado los paquetes de los repositorios de hylafax y demás, pero la verdad es que haciéndolo a mano como comentaba al principio se ve en detalle como operada cada uno de los sistemas involucrados y si tenemos un problema, sabremos donde ir a buscar con más sencillez. Exactamente lo mismo que ocurre con el propio sistema Asterisk, cuando lo compilamos desde las fuentes al principio de todo.

Seguramente salgan 1001 problemas más que yo no haya contemplado aquí. Si tenéis alguna inconveniencia escribidla y trataremos de analizarla en el detalle para perfeccionar este mensaje al máximo.

De nuevo, agradezco vuestro interés por Asterisk y por este blog, al igual que vosotros agradeceréis el interés aquí mostrado. No nos dejes caer en la tentación y líbranos del mal. Amén.

Obteniendo un control exhaustivo de llamadas con CDR-Stats

Una de las funciones más interesantes que tiene Asterisk casi por defecto, es el hecho de guardar todo un registro completo de eventos acontecidos, todos aquellos movimientos a través del Plan de Marcación en tiempo real. Y estos eventos pueden quedar registrados de diversas formas, sea en ficheros CSV (comma separated values) formato muy común de almacenaje de datos en ficheros de texto planos, o registros en una base de datos SQL (Postgre SQL, MySQL, etc).

En mi caso, he mostrado un gran interés en registrar los eventos en una base de datos MySQL puesto que ha sido hasta la fecha, pese a ser propietaria de la todopoderosa Oracle (y porque no decirlo, Sun Microsystems me caía mejor como corporación), la que más he manejado en mi vida. Quizá algún día empiece a indagar en el mundo del elefantito Postgre, pero de momento la combinación MySQL y el gestor del gestor, valga la redundancia, phpMyAdmin, simplifica mi existencia.

Ahora, tras esta breve introducción, voy a explicar cómo combinar estos dos elementos, el registro detalle de llamadas (CDR, call detail record) con una base de datos MySQL, y poder obtener una interfaz genérica, ya preparada, y de gran utilidad para manipular estos registros de llamada: CDR-STATS (créditos a Areski Belaid por este excelente trabajo de integración)

Pues como siempre, empecemos manos a la obra.

En primer lugar, toca configurar el sistema Asterisk para que vaya almacenando de forma automática todo el registro de llamadas en la base de datos, y por ende, necesitamos la base de datos instalada en nuestro sistema. Para ello lo más sencillo, en el sistema en que nos encontramos (Ubuntu Server), es instalar LAMP (Linux + Apache + MySQL + PHP) ya que toda esta combinación nos servirá en un futuro cada una de sus partes (Apache y MySQL son requeridos por Cdr-stats y PHP por phpMyAdmin).

Existe un comando en Ubuntu Server muy sencillo que nos permitirá hacer la instalación de este sistema en cuestión de segundos: tasksel (veremos aquella pantalla que vimos en su día durante la instalación del sistema base). Ahí seleccionamos Servidor LAMP y validamos, instalándose automáticamente todo. Nos pedirá algunos detalles de instalación, como las contraseñas de acceso root a nuestra base de datos MySQL que necesitaremos para la posterior configuración.

A continuación instalamos phpMyAdmin para la gestión sencilla como comentaba antes: aptitude install phpmyadmin. Nos pedirá entre otros temas, la contraseña de administrador (root) de nuestra base de datos Mysql, se la proporcionamos. Una vez instalado, con un navegador apuntando a nuestro servidor Asterisk podemos acceder (o a la dirección donde este ubicado nuestro servidor web si lo tenemos independiente al servidor asterisk): http://servidorasterisk/phpmyadmin. Ahí podremos acceder de momento con el usuario “root” y la contraseña de administrador a nuestras bases de datos.

Ahora tenemos que empezar a diseñar la base de datos donde vamos a almacenar nuestros CDR de Asterisk.  De momento, creamos un archivo de texto que llamamos por ejemplo, dbasterisk.sql y dentro agregamos:

CREATE DATABASE asterisk;
GRANT INSERT
ON asterisk.*
TO asterisk@localhost
USE asterisk;

CREATE TABLE `cdr` (
`calldate` datetime NOT NULL default ‘0000-00-00 00:00:00’,
`clid` varchar(80) NOT NULL default ”,
`src` varchar(80) NOT NULL default ”,
`dst` varchar(80) NOT NULL default ”,
`dcontext` varchar(80) NOT NULL default ”,
`channel` varchar(80) NOT NULL default ”,
`dstchannel` varchar(80) NOT NULL default ”,
`lastapp` varchar(80) NOT NULL default ”,
`lastdata` varchar(80) NOT NULL default ”,
`duration` int(11) NOT NULL default ‘0’,
`billsec` int(11) NOT NULL default ‘0’,
`disposition` varchar(45) NOT NULL default ”,
`amaflags` int(11) NOT NULL default ‘0’,
`accountcode` varchar(20) NOT NULL default ”,
`userfield` varchar(255) NOT NULL default ”
);

ALTER TABLE `cdr` ADD `uniqueid` VARCHAR(32) NOT NULL default ”;
ALTER TABLE `cdr` ADD INDEX ( `calldate` );
ALTER TABLE `cdr` ADD INDEX ( `dst` );
ALTER TABLE `cdr` ADD INDEX ( `accountcode` );

De momento no interesa demasiado eliminar ningún campo porque si no luego podremos tener problemas con el CDRStats, que aun solucionables, no deseamos complicarnos la vida de momento.

Con esto lo introducimos en nuestra base de datos con el sencillo comando, que solo nos pedirá nuestra clave de administrador de MySQL
mysql –p  < dbasterisk.mysql

Lo segundo que necesitamos es instalar el módulo de Asterisk cdr_mysql. Seguramente durante la instalación del Asterisk-Addons (en caso de la versión 1.6.2) o directamente durante la instalación de Asterisk (versión 1.8), con la opción make menuconfig pudimos seleccionar el módulo cdr_mysql. En otro caso nos tocaría volver a recompilar Asterisk-Addons incluyendo este módulo. En caso que no, vamos a donde descomprimimos el tarball de Asterisk-addons, y realizamos la siguiente secuencia:

# make menuconfig (seleccionamos debajo del submenú Call Detail Recording cdr_msql)
# ./configure
# make
# make install

Y ya tendríamos preparado el modulo. Solo quedaría configurarlo para empezar a registrar llamadas en nuestra base de datos. Existe un fichero de configuración en /etc/asterisk llamado cdr_mysql.conf que retocaremos asi:

[global]
hostname=localhost
dbname=asterisk
table=cdr
user=asterisk
// A continuacion crearemos un usuario llamado asterisk desde la interfaz de phpmyadmin
password=contraseñadeasterisk
port=3306
// Puerto por defecto de MySQL y si lo cambiamos tendremos que cambiarlo aquí también

Aparte, bajo el contexto [columns] debemos eliminar todos los comentarios “;” que empiecen por alias y static.

Por otro lado nos toca configurar el nuevo usuario asterisk. Dentro de phpMyadmin accediendo por la interfaz web como comente antes, entramos en la opción Privilegios, seleccionamos el usuario asterisk que en teoría debería haberse creado junto a la base de datos y le damos al botón de edición, o creamos uno nuevo seleccionando “Agregar nuevo usuario”.

Aquí solo tenemos que darle permisos totales para acceder a la base de datos (si es que solo vamos a utilizar esta base de datos para Asterisk, sino, ya seleccionamos privilegios básicos de datos y no de estructura y menos de administración) y damos a Continuar (se actualizan los privilegios). Luego en la contraseña, le ponemos la contraseña que especificamos antes y le volvemos a dar a continuar para actualizar. Esto es todo.

Ahora simplemente accedemos a la CLI y cargamos el módulo mysql con el comando: reload cdr_addon_mysql.so

Aparte podemos comprobar que esta todo OK si ponemos el comando cdr show status en el apartado Registered Backends aparecerá uno que pone “mysql”.

Ya tenemos nuestro Asterisk “registrando” todas las llamadas en nuestra base de datos. Considerar que en función del espacio de nuestro sistema tendremos que purgar eventualmente el registro para no saturar la base de datos en función del uso que le demos a nuestra máquina. Aunque esto ya es administración de SQL y debería ir dedicado en otro capítulo.

Ahora viene la configuración de CDR-Stats para poder ver de forma “bonita” ese registro de llamadas, aunque realmente podríamos crear con lo que tenemos cualquier interfaz en php que acceda a esta tabla (cdr) de la base de datos (asterisk) en función de nuestras necesidades. Quiza algún día próximo haga alguna aproximación a esto para poder crear un sistema muy básico y así generar un informe concreto de rápido acceso desde una interfaz web, ya que he podido observar que CDR-Stats, aún siendo muy bonito, no llega a ser todo lo completo que uno podría llegar a necesitar en un momento determinado, dada su “genericidad” y para obtener información de alta calidad, requiere dar muchos pasos (crear muchos filtros, con la consiguiente pérdida de tiempo si especialmente se trata de un trabajo diario repetitivo), en vez de poder obtener un informe concreto de un solo golpe (por ejemplo número de llamadas atendidas por cada extensión, o número de llamadas salientes por cada extensión y tiempo total consumido). Incluso podríamos filtrar por tipo de llamadas por extensión y tiempo consumido (a móviles, a fijos y demás), al puro estilo “Facturador Telefónico”. Supuestamente existen software muy avanzados de facturación para Locutorios (Asterisk es un sistema ideal para este tipo de negocios de bajo coste) y otros Retailers que se dediquen a este mundillo (Expendedores de tarjetas de llamadas, etc). Este software se llama A2Billing (asterisk2billing), y ha sido creado por la misma empresa que pertenece Areski Belaid, creador de CDR-Stats como comente antes.

En la página web del creador existe documentación sobre su instalación, pero debo decir que es de muy baja calidad, y siguiéndola paso a paso yo no conseguí hacerlo funcionar. Y tengo constancia que muchos otros tampoco lo consiguieron.  Hay que considerar que CDR-Stats no está pensado originalmente, para ser integrado en una maquina Asterisk a modo “Standalone” sino como un módulo de sistemas completos Asterisk tipo FreePBX o Elastix. Pero siguiendo la filosofía de este blog, haciendo esto desde 0 estamos en contacto con la “naturaleza” del sistema Asterisk y estaremos más cubiertos ante la posibilidad de fallos o desastre sin la complejidad de un sistema prefabricado y preconfigurado.

En primer lugar nos toca instalar la última versión de Python, por los tiempos que corren ahora, se trata de la versión 2.6: aptitude install python2.6

Luego viene un modulo de Python utilizado por este sistema muy útil para la creación de sitios web con Python: Django en la web http://www.djangoproject.com/download/

La instalación de este es muy sencilla tras ser descargado:
# wget http://www.djangoproject.com/download/1.2.4/tarball/
// La versión puede variar con el momento también
# tar xzvf Django-1.2.4.tar.gz
// Igual lo que viene va en función de la versión
# cd Django-1.2.4
# pythong setup.py install

Luego necesitamos otro módulo de Python, Dateutils, lo podemos obtener de los repositorios de Python, pero para ello necesitamos la herramienta easy_intall:
# aptitude install python-setuptools
# easy_install DateUtils

Y a continuación, otro llamado South:

# easy_install South

Ahora viene un módulo de Django, llamado Uni Form. En este caso la última versión del módulo se puede descargar de la página del Autor: https://github.com/areski/django-uni-form/downloads

# wget https://github.com/areski/django-uni-form/tarball/0.8.0 –no-check-certificate
# tar xvf 0.8.0
// En estos casos como antes, estamos sujetos a la version, creo que es importante conocer commandos de Linux a la perfeccion para poder adaptarse con comodidad a estos commandos en function del tiempo en el que leamos este articulo
# cd areski-django-uniform-xxxxx…. (aquí viene el directorio recién descomprimido)
# python setup.py build
# python setup.py bdist_egg
# easy_install dist/django_uni_form-0.8.0-py2.6.egg (sujeto a versión de uniform y python también)

Ya tenemos el sistema listo, solo falta descargamos finalmente el personaje principal de tidi esto: CDR-Stats. Tenemos dos opciones, con el tarball, o con la última versión git subida por el autor. Para no complicarnos la vida nada, lo haremos con el Tarball y seguir en la tónica de hasta ahora, aunque invito fervientemente a aprender a utilizar git puesto que es un sistema de Control de Versiones excelente y con 4 comandos básicos, se vuelve muy sencillo de manejar.

# wget https://github.com/areski/cdr-stats/tarball/v1.1.0 –no-check-certificate
# tar xvf v1.1.0
// Y ahora preparamos ya lo descomprimido para ubicarlo en el lugar que sera ejecutado con nuestro Apache automáticamente justo en el ultimo paso
# mkdir /usr/share/django_app
# cp –r areski-cdr-stats-(directorio recién descomprmido)/cdr_stats /usr/share/django_app

Así tendremos preparado el sistema cdr_stats en su directorio de “instalación” como veremos mas adelante. Entramos en esa carpeta /usr/share/django_app/cdr_stats y editamos el fichero settings.py:

En la línea de ADMINS descomentamos y ponemos nuestro nombre y correo electrónico para figurarnos como administrador del sistema CDR-Stats

Luego en las sección Databases, tenemos que poner los parámetros de conexión de nuestro sistema MySQL:
‘ENGINE’:’mysql’,
‘NAME’:’asterisk’,
‘USER’:’asterisk’,
‘PASSWORD’:’contraseña_del_usuario_asterisk’

Seguimos adelante, en la sección LANGUAGE_CODE ponemos ‘es-es’, en TIMEZONE ‘Europe/Madrid’ (si somos de España)
Sino buscamos en http://en.wikipedia.org/wiki/List_of_tz_zones_by_name

Más abajo, en la sección: MEDIA_URL vamos a poner la dirección local de nuestro asterisk y el puerto 9000 quedando algo asi:
MEDIA_URL=’http://ip_del_servidor_web:9000/resources/’ (no dejar localhost porque podremos tener problemas si accedemos desde otro sitio que no sea el servidor con la carga de recursos)

Luego vamos a generar una clave privada única para cambiar la que viene por defecto en la sección SECRET_KEY con el siguiente comando de consola:
tr -dc A-Za-z0-9 < /dev/urandom | (head -c $1 > /dev/null 2>&1 ||head -c 50) && echo

Y finalmente en la parte de este fichero de configuración, en INSTALLED_APPS tenemos que comentar la línea  #’dilla’

Ahora crearemos un enlace simbolico para los elementos media de python que usaremos en nuestro entorno (supuestamente estamos en la carpeta /cdr_stats/admin de /django_app

ln -s  /usr/local/lib/python2.6/dist-packages/django/contrib/admin/media/ /usr/share/django_app/cdr_stats/admin

Finalmente sincronizamos la base de datos con el sistema Python, necesitamos un módulo adicional para poder  trabajar con MySQL y Python conjuntamente:
#aptitude install python-mysqldb
# python manage.py syncdb

Ahora pedirá una serie de datos sobre el primer usuario de Administrador, los rellenamos, nombre de usuario, email, contraseña, etc. Con esto podremos acceder a la interfaz web de CDR-Stats por primera vez. Si queremos crear otros superusuarios basta con que ejecutemos el siguiente comando:
python manage.py createsuperuser –username=usuarioejemplo –email=usuarioejemplo@ejemplo.com

Con esto ya tendremos el sistema base de CDR_Stats configurado por completo. Ahora solo necesitamos probar que el sistema funciona bien, antes de “automatizarlo” en nuestro Apache para futuros usos:
python manage.py runserver 0.0.0.0:9000

Y entramos a la interfaz web http://ip_servidor_web:9000 nos redirigirá a la pagina de CDR-Stats nuestra, ahí accedemos con el usuario y contraseña creados antes. Si podemos verla sin problemas (Recordar que usa Flash asi que necesitaremos el plugin en nuestro navegador adecuado), entonces ya tendremos todo listo.

Finalmente vamos a configurar el servidor Apache para que ejecute el soft ware automáticamente al arrancar nuestro servidor. Necesitamos cargar un modulo de Apache para poder ejecutar programas en Python:
aptitude install libapache2-mod-python

Creamos un fichero llamado cdr_stats.conf dentro de la carpeta /etc/apache2/sites-available/ con la siguiente información:

Listen *:9000
<VirtualHost *:9000>
DocumentRoot /usr/share/django_app/cdr_stats/
ErrorLog /usr/share/django_app/err-cdr_stats.log
<Location “/”>
SetHandler mod_python
PythonHandler django.core.handlers.modpython
PythonPath “[‘/usr/share/django_app/cdr_stats/’,’/usr/share/django_app/’] + sys.path”
SetEnv DJANGO_SETTINGS_MODULE cdr_stats.settings
PythonDebug On
</Location>
<location “/media”>
SetHandler None
</location>
</VirtualHost>

Ahora creamos un enlace simbolico a este fichero, en la carpeta sites-enabled:
ln -s /etc/apache2/sites-available/cdr_stats.conf /etc/apache2/sites-enabled/

Reiniciamos el servidor Apache: service apache2 restart

Y aunque suene poco profesional, como diría nuestro amigo Porky, That’s all Folks! Deberíamos de ver, accediendo de nuevo a la dirección anterior en  nuestro navegador web, el sistema CDR-Stats en funcionamiento.

Si queda algún fleco o alguna duda sin resolver en este mensaje, no duden en ponerme un comentario y actualizare esto para dejarlo lo más completo posible.