Introduciendo un Proveedor SIP: Parte 2

Tras la migracion, y aun a la espera del retorno de la tarjesta TDM410P enviada en garantia, hoy voy a hacer una pequeña explicacion de las ultimas modificaciones introducidas a nuestro sistema Asterisk, concretamente a nivel de DialPlan, para en detalle, el funcionamiento del Proveedor SIP que configuramos el otro dia y por otro lado, algunos retoques para darle un poco mas de nivel a nuestro sistema, como una pequeña operadora automatica de pruebas.

Realmente aqui se vera gran parte del codigo contenido en nuestro fichero “extensions.conf” y un poco la explicacion de cada atributo.

[operadorip]
exten => 851123456,1,NoOp()
exten => 851123456,n,Goto(s,1)
exten => sirlouen,1,NoOp()
exten => sirlouen,n,Goto(s,1)

Si recuerdan, el otro dia pusimos en el contexto del provedor SIP dentro del sip.conf, llamado “operadorip”. Este contexto vendra directamente aqui.

La primera vez que hable del DialPlan no explique exactamente a que se referia cada argumento de la linea exten=>

En primer lugar, exten, se refiere como su nombre indica, a la extension marcada a la que va a hacer referencia como primer argumento. Esto es lo mas extendido y utilizado por defecto. En este caso, la extension, hablamos del numero DDI que nos ofrece el operador IP ya que de alguna forma es como lo reconocera como primera “entrada” nuestra centralita. En algunos casos, el proveedor IP te ofrece un numero de usuario adicionalmente, y este numero de usuario tambien lo entrega el operador IP sustituyendo al numero DDI, de forma casi aleatoria segun comprobe tras diversas pruebas. Por eso decidi poner las dos posibilidades.

Como segundo argumento, es el numero de prioridad en la lista de ejecucion. Lo tipico es poner en la primera linea el 1, en la segunda el 2, etc. Pero si ponemos en la primera el 1 y luego la n, significa que aumentamos el contador de prioridad linealmente, 1, n+1 (2), n+1 (3), etc. Esto es util si por ejemplo en un futuro tenemos intencion de meter mas lineas intermedias, no tengamos que cambiar el numero de prioridad a toda la secuencia completa, algo engorroso y que puede dar lugar a errores.

El tercer argumento hace referencia a la funcion que va a cumplir esa linea. En mi caso, siguiendo un buen consejo que me dieron, lo ideal seria poner NoOp (sin operacion), para poder asi asignarle el elemento 1 por defecto. Esto es una buena practica en general ya que si luego creamos Macros (equivalente a plantillas para secuencias del Plan de Marcacion), esto hace que exista cierta uniformidad y estandarizacion. Tampoco es crucial escribir asi, pero desde que se creo el Copy & Paste tampoco supone una gran inconveniencia y nos aportara mas que nos rebajara.

Los siguientes Argumentos en embos casos, son condicionales GO TO, tipicos en programacion. La funcion GoTo recibe 3 parametros siendo como primer parametro, un contexto, si solo se dan dos, se conserva en el contexto en que nos encontremos. El segundo, seria la posicion de marcacion dentro de ese contexto. S viene a ser la posicion de inicio por defecto. Donde suele entrar todo (hace referencia a Start, comienzo) al entrar en un contexto. Finalmente indicamos el lugar de la prioridad donde queremos entrar. Tambien con la funcion Goto podriamos pasar 1 solo argumento, esto es el lugar dentro del a prioridad (y consideraria la posicion de marcacion y el contexto donde actualmente nos encontrasemos), tambien podemos pasar una bandera asociada a un nivel de prioridad como veremos mas adelante.

Con esto, de alguna forma, si nos llaman a nuestro numero DDI, “ya estariamos dentro de la centralita”, ahora tocaria a traves de un Contestador Automatico, manejar esta llamada

exten => s,1,NoOp()
exten => s,n,Answer
exten => s,n,Background(menu)
exten => s,n,WaitExten(20)

Esto es bastante sencillo. Igual que vimos con anterioridad, recogemos la llamada con Answer, y con Background ponemos un sonido que tendremos registrado en nuestro directorio /var/lib/asterisk/sounds.
Hay dos formas de crear sonidos
1. A traves de una marcacion con la funcion Record, grabariamos nuestros propios sonidos
2. Directamente introduciendo la pista de audio en la carpeta indicada con el nombre en cuestion y segun el formato .gsm, .wav, etc que tengamos especifcado dentro de los codecs soportados en este contexto.
Finalmente tenemos la funcion WaitExten que basicamente realiza la operacion de espera a que se marque un digito durante los segundos pasados como parametro. Este digito entra como marcacion DTMF y como comente en otra ocasion, aqui se originaron problemas por parte del operador IP, a raiz de las malas latencias, que al final consegui solucionar en el fichero de configuracion de disposistivos SIP utilizando el modo DTMF “inband”
exten => 1,1,NoOp()
exten => 1,n,Playback(ext1000)
exten => 1,n,Goto(extensiones_internas,1000,1)
exten => 2,1,NoOp()
exten => 2,n,Playback(ext1001)
exten => 2,n,Goto(extensiones_internas,1001,1)
Una vez marcado el digito por DTMF iriamos a la posicion de marcacion, en este caso pongo dos ejemplos sencillos, lo unico especial, la funcion Playback que a diferencia de Background no espera una marcacion, simplemente reproduce un mensaje y continua hasta la siguiente orden. En este caso, cambiamos de contexto y ya finalmente nos vamos a nuestro contexto “privado” donde estan ubicadas las extensiones de nuestra oficina tal y como configuramos con anterioridad.
Ahora vendria la otra perspectiva, desde “dentro” hacia el exterior a traves del proveedor SIP.
En este caso por motivos logicos de “seguridad” no nos interesaria que alguien pudiera acceder a traves de las marcaciones DTMF en el mismo contexto “operadorip” y ser capaz de llamar al exterior. Por esto, la idea es que esto solo pueda marcarse desde el contexto “privado” donde se encuentran nuestras extensiones.
En este caso la marcacion es un tanto especial y tenemos que introducir nuevos conceptos:
;Salida de llamadas Nacionales
exten => _[689]XXXXXXXX,1,NoOp()
exten => _[689]XXXXXXXX,n,Dial(SIP/${EXTEN}@netelip,30)
exten => _[689]XXXXXXXX,n,Hangup()
Como podemos ver, aqui aceptamos un total de 9 posiciones. Bueno parecen mas, pero aqui explico el formato especial de marcacion que he tenido en cuenta para este caso:
En primer lugar, si vamos a usar caracteres especiales como X,N o Z necesitamos poner delante la barra baja.
En segundo lugar, observamos los tres valores 6,8,9 contenidos entre corchetes. Al estar contenidos entre corchetes significa los posibles valores que puede tomar el primer digito, solo el 6 (moviles), 8 (numeros geograficos virtuales) y 9 (numeros geograficos de España). Tambien podriamos tener un guion tipo [67-9] en este caso estariamos considerando los valores 6,7,8 y 9 seria lo mismo que [6-9]
En tercer lugar tenemos digitos especiales. X significa cualquier valor entre 0 y 9, Z entre 1 y 9 y N entre 2 y 9. En este caso seguramente seria mas eficaz separar los moviles y los fijos dado que podriamos en un segundo nivel restringir las llamadas a numeros especiales tipo 902, 901, etc eliminando la posibilidad con [89]ZXXXXXXX. Aqui tenemos tantas posibilidades como queramos.
Una vez marcada esta secuencia, nos encontramos con la Funcion Dial, que al igual que utilizado para marcar extensiones en este caso con la variable ${EXTEN} recogemos lo marcado en la posicion de marcacion y lo “enrutamos” a traves del contexto sip indicado tras la @ en este caso nuestro Proveedor IP. El ultimo parametro 20, es el tiempo que esperara tras marcar para que recoja tono la llamada, en otro caso colgara.
Entendido esto podriamos crear sistemas de marcacion todo lo complejo que se nos ocurriesen. Y muy util para la creacion de plantillas, y para la generacion de extensiones de manera semi-automatica puesto que por parte del dialplan no seria necesario apenas escribir codigo si el patron de las extensiones es equivalente.
Con esto doy una breve revision de la interrelacion de un proveedor IP y el Plan de Marcacion de nuestro sistema para poder darle uso. Pero el Dial Plan tiene mucha miga por dentro, miles de funciones. Seguire en sucesivos articulos poniendo mas ejemplos sobre posibles opciones que se me ocurran y que mas concretamente sean muy utiles en un entorno de produccion/oficina.

El Terror a las Pantallas Negras

Hoy tenia ganas de escribir sobre algo relacionado a este mundo pero que no demasiado tiene que ver con el mundo Asterisk en particular.

Como bien dice el titulo de este mensaje, hoy estuve reflexionando sobre el terror a las pantallas negras. Es decir, el miedo a las shells, consolas, etc. Desde tiempos inmemoriables, trabajar con sistemas tipo Windows, las pantallas negras se han asociado a problemas en el sistema, o momentos de arranque. Pero… y si durante el arranque nunca se llegaba a pasar de esa pantalla negra? En el mundo de la administracion de sistemas, para el usuario comun seria asi como “Mi ordenador no enciende, se me queda en la pantalla negra”.

Pero ahora este mensaje lo percibo desde el punto de vista del administrador de sistemas, especialmente el administrador Linux, que debe lidiar diariamente con pantallas negras por todas partes. Pero personalmente sigo sufriendo un poco del momento “Windows” y el estress de ¿ahora que hacer sin mi gestor de ventanas?.

Por un lado creo que es motivacion de que se pierde la puerta a la informacion absoluta: Internet (aunque existan alternativas tipo Lynx, son demasiado odiosas para ser ciertas).

Hoy por ejemplo, en en una de mis estaciones de trabajo, he querido actualizar el Kernel para obtener una nueva funcionalidad (OpenVZ funcionando sobre un kernel 2.6.32) y tras la actualizacion, al reiniciar, mil errores varios (faltaban las nuevas cabeceras del Kernel en el area de compilacion) y tras una carga de mas del triple de lo normal, el sistema de ventanas no arrancaba.

Pero pensando en frio, la solucion llego rauda:

1. Arrancar la shell, editar el fichero xorg.conf para utilizar un driver sencillo, el “Vesa” por ejemplo es infalible. Ademas en la Sub Seccion del Driver de Pantalla, colocar una resolucion fiable, “1280×1024” para tener las cosas mas claras (Mode “1280×1024”)

2. Iniciar las X, “startx”

3. Ahora si arrancan, es momento de acceder al navegador para descargar algo que pueda solucionar la vida. En mi caso, analizando el error del arranque del gestor anterior, observe que daba un problema al intentar cargar el driver fglrx de la grafica ATI. Esto probablemente fuera, porque aun no estaba “cargado” en el nuevo Kernel.

4. Aprovecho y me bajo el ultimo driver propietario de ATI y lo instalo. Una de las instalaciones mas sencillas del sistema. Una cosa curiosa es que he observado que debo ejecutarlo en modo shell con un superusuario. Algo asi como:
# sudo su –
# sh driver_ati_utlimo.run
He probado en otras ocasiones a instalar con la GUI integrada en el propio sistema de ventanas y parece que no ejecuta por alguna razon, exactamente la misma operacion.

5. Finalmente volver a reeditar el fichero xorg.conf para que apunte al nuevo recien cargado driver fglrx y reiniciar el Equipo para comprobar…

Que arrancan las X en Alta Definicion. Vaya por dios.

Escribo esto un poco como auto-reflexion, para recordarme a mi mismo que en esos momentos que llega la pantalla negra y pienso “ha llegado el momento de formatear”, realmente no es tan critico y existe una salida no muy compleja a apenas unos pocos golpes de teclado.

Tambien escribo esto para no olvidar que este Blog esta diseñado para empezar desde 0, y mejorar la curva de aprendizaje concretamente del sistema Asterisk, pero sinergicamente del sistema base: Linux. Esto no es un tutorial, pero si una aproximacion de una idea de como saber actuar en estos momentos de Terror. Aunque la verdad que estos casos trabajando con Asterisk no deberian de ocurrir demasiado, a no ser que tengamos una Estacion de Trabajo y de Pruebas con Asterisk en Debian, y requiramos la interfaz grafica por ejemplo, como comente en uno de los primer mensajes, para correr un SIP Phone tipo Ekiga.

Una Nueva Maquina para el Sistema

Por razones de la vida, he encontrado una maquina HP Proliant ML 110 de Cuarta Generacion (G4), abandonada en una de las instalaciones. Realmente no estaba abandonada, pero estaba siendo infrautilizada, asi que he decidido tomarla prestada, para cambiarla por el servidor que actualmente estoy utilizando, que es parecido, pero no es HP.

Realmente este servidor no trae nada especial, ya que en realidad la serie ML110 vienen a ser Workstations con procesadores de Servidor, y en este caso una placa que soporta hasta 8GB de memoria ECC DDR2. De igual forma como de momento no estoy llevando el servidor a niveles de produccion, he preferido instalarle buena cantidad de memoria no-ECC para que resulten las cosas como corresponden, ya que originalmente solo traia un modulo de 512Mb DDR2 PC5300 ECC que aunque sea Linux, ya no me convence esta cantidad demasiado para ninguna labor de hoy en dia. He montado 2 memorias de 2Gb DDR2 PC6400 no-ECC en Doble Canal. El resto por defecto de fabrica. Llegado el momento, aqui tambien montare la Tarjeta Digium que envie el otro dia en Garantia ya que posee varios slots  PCI, mas que el PC-Workstation que estaba utilizando con anterioridad (y quiza en un futuro tambien poder montar alegremente la tarjeta de Primario para las pruebas correspondientes)

Este mensaje realmente lo escribo como una primera aproximacion de lo que seria una rapida migracion de sistema, para demostrarme a mi mismo, que aun bajo una caida de mi centralita, la reposicion seria cuestion de minutos/horas desde mi atencion.

En primer lugar, instalo Ubuntu Server, monto el sistema RAID con mdadm y LVM2 encima en tres particiones tal y como se explico en el mensaje:
http://www.10000horas.com/2010/08/08/primer-sistema-base-ubuntu-server-y-md-raid/

En segundo lugar, la instalacion del Sistema Asterisk, paso facil y bastante “automatizado” de momento:
http://www.10000horas.com/2010/08/09/manos-a-la-obra-con-asterisk/

En tercer lugar, en el servidor antiguo simplemente copio los directorios que han incurrido en posibles modificaciones (realmente son unos pocos ficheros, pero me gustaria conservar todos los pequeños cambios y no quiero que se me olvide nada). En modo super usuario en el servidor antiguo:

# cd etc
# tar -cf asterisk.tar asterisk/
# scp asterisk.tar ipdelnuevoservidor:/tmp/
# tar -cf dahdi.tar dahdi/
# scp dahdi.tar ipdelnuevoservidor:/tmp/

NOTA (26/10/2010): Tras ampliar mi abanico de conocimientos he observado que se requieren mas carpetas para migrar el sistema completo. La verdad es que no me lei a fondo la documentacion con respecto a los directorios que utiliza el sistema Asterisk por defecto.

El comando “magico” (agradecimientos a Elio Riojano) para conseguir un backup completo de asterisk: tar cvfj asterisk-backup-`date +%Y%m%d-%H%M%S`.tgz /etc/asterisk /var/lib/asterisk /var/spool/asterisk /etc/dahdi
Seguramente se pueda completar aun mas, pero para mis propositos actuales, me sobra y me basta.

Finalmente, copiamos estos ficheros de nuevo a nuestro directorio /etc del nuevo servidor Asterisk. Aqui voy a dar algunos pasos innecesarios realmente, pero que podrian ser utiles y no son dañinos realmente

# cd /etc
# mv /tmp/asterisk.tar /etc/
# mv /tmp/dahdi.tar /etc/
# mv asterisk/ asterisk.old/ (opcional)
# mv dahdi/ dahdi.old/  (opcional)
# tar -xf dahdi.tar
# tar -xf asterisk.tar

Ahora ya tenemos configurado el sistema tal y como lo teníamos antes. Probamos si funciona y si esta todo correcto, podriamos borrar esos directorios .old o mantenerlos por si necesitamos mirar algo (aunque en teoria para eso esta el directorios de ejemplos (samples) que creamos durante la compilacion, asi que estos datos dejarlos ahi seria innecesario realmente).

Finalmente y opcional hasta este punto, copiar las grabaciones que hicimos (si son de calidad, no es mi caso en este momento)

# tar -cf sounds.tar /var/lib/asterisk/sounds/
# scp sounds.tar ipdelnuevoservidor:/tmp/

Y luego justo al reves, copiamos de tmp a sounds en nuestro nuevo servidor, exactamente igual que hicimos antes con las configuraciones

Hacemos algunas llamadas de pruebas, tanteamos nuestro servidor SIP externo, y en teoria ya deberia estar todo funcionando.

Tiempo estimado total: 2 horas, de las cuales 1 hora y media son desatendidas entre instalaciones y compilaciones.

La verdad que con esta gestion he conseguido autodesmitificarme que la migracion ante una posible incidencia grave, resulta verdaderamente sencilla. Y en este caso ya hemos identificado tres directorios que seriainteresante tenerlos en una rutina de backup eventual para poder reestablecer el sistema en caso de tener problemas, quiza con cron. Ya veremos resumidamente algunas rutinas basicas con cron, para establecer entre otras cosas, actualizaciones de sincronizacion de hora efectivas, y como aqui planteado, backups automaticos.