La importancia de una línea de código: como hacer debug a tu configuración de Asterisk

20 Mar

El fin de semana por la noche recibí una llamada de un cliente nuestro solicitando apoyo para revisar el estado de su E1. Al parecer habían estado con el servicio de telefonía caido todo ese día, y tras horas de conferencia con su carrier no habían podido encontrar la razón por la cual el servicio del E1 no levantaba. Asterisk podía hacer llamadas entre extensiones, pero no tenían comunicación con el exterior.

Por experiencia, mi primer acercamiento fue revisar el archivo chan_dahdi.conf, que es el responsable del E1. Lo abrí pero no noté nada fuera de lo normal, así que desde la consola de Asterisk procedí a descargarlo de memoria y cargarlo nuevamente, esperando que arrojara algo de información. El resultado fue algo como lo siguiente:

server1*CLI> module load chan_dahdi.so
[Mar 20 02:03:52]   == Registered application 'DAHDISendKeypadFacility'
[Mar 20 02:03:52]   == Registered application 'ZapSendKeypadFacility'
[Mar 20 02:03:52]   == Parsing '/etc/asterisk/chan_dahdi.conf': [Mar 20 02:03:52] Found
[Mar 20 02:03:52] WARNING[9583]: config.c:778 process_text_line: parse error: No category context for line 6 of /etc/asterisk/chan_dahdi.conf
[Mar 20 02:03:52] ERROR[9583]: chan_dahdi.c:12728 setup_dahdi: Unable to load chan_dahdi.conf
[Mar 20 02:03:52]   == Registered channel type 'DAHDI' (DAHDI Telephony Driver w/PRI)
[Mar 20 02:03:52]   == Manager registered action DAHDITransfer
[Mar 20 02:03:52]   == Manager registered action ZapTransfer
[Mar 20 02:03:52]   == Manager registered action DAHDIHangup
[Mar 20 02:03:52]   == Manager registered action ZapHangup
[Mar 20 02:03:52]   == Manager registered action DAHDIDialOffHook
[Mar 20 02:03:52]   == Manager registered action ZapDialOffHook
[Mar 20 02:03:52]   == Manager registered action DAHDIDNDon
[Mar 20 02:03:52]   == Manager registered action ZapDNDon
[Mar 20 02:03:52]   == Manager registered action DAHDIDNDoff
[Mar 20 02:03:52]   == Manager registered action ZapDNDoff
[Mar 20 02:03:52]   == Manager registered action DAHDIShowChannels
[Mar 20 02:03:52]   == Manager registered action ZapShowChannels
[Mar 20 02:03:52]   == Manager registered action DAHDIRestart
[Mar 20 02:03:52]   == Manager registered action ZapRestart
[Mar 20 02:03:52]  Loaded chan_dahdi.so => (DAHDI Telephony w/PRI)

De aquí lo que importa es la línea que nos da el error:

[Mar 20 02:03:52] WARNING[9583]: config.c:778 process_text_line: parse error: No category context for line 6 of /etc/asterisk/chan_dahdi.conf

Tras abrir el archivo chan_dahdi.conf nuevamente y prestar un poco más de atención, las primeras líneas indican lo siguiente:

;autogenerated by /usr/sbin/wancfg_dahdi do not hand edit
;autogenrated on 2011-10-11
;Dahdi Channels Configurations
;For detailed Dahdi options, view /etc/asterisk/chan_dahdi.conf.bak

language=es

[trunkgroups]

[channels]
context=default
usecallerid=yes
hidecallerid=no
callwaiting=yes
usecallingpres=yes
callwaitingcallerid=yes

Y aquí es donde tras poner atención, notamos que el error proviene de una sola línea de código, el language=es está fuera de cualquier contexto, y esto provoca un error de parsing al momento de cargar el módulo, lo que impide que el canal se cargue correctamente y por lo tanto, el E1 nunca levante.

Entonces, ¿Cuales son los pasos para hacer un debug correcto de la configuración de Asterisk?

Los sistemas informáticos, a diferencia de los seres vivos, no cambian por si solos. Si nuestro sistema estaba bien de principio y de pronto algo dejó de funcionar es porque algo cambió. Una manera sencilla de ver los archivos de configuración en el orden en que fueron recientemente modificados es usar el comando ls:

ls -lSt /etc/asterisk | head -n 20

Con este comando ordenaremos los archivos de configuración de más reciente a menos reciente, mostrando solo los últimos 20 modificados. De ahí, podemos ir retrocediendo en nuestros pasos hasta que demos con la línea de código que alteramos y el sistema se restituya tras recargar el módulo o reiniciar Asterisk.

Si tenemos localizado el archivo con el problema, pero no sabemos exactamente en que línea está, el CLI de Asterisk puede resultar muy útil. Solo debemos asegurarnos que el log de eventos se arroja a consola editando el archivo /etc/asterisk/logger.conf

#/etc/asterisk/logger.conf
[general]

[logfiles]
console => warning,error,notice,debug
full => notice,warning,error,verbose

Como se aprecia en el archivo, estamos diciéndole a Asterisk que envie a consola toda la información relacionada con eventos warning, error, notice y debug (nota: el debug arroja MUCHA información, si hemos resuelto el problema lo recomendable es retirarlo del archivo hasta la siguiente vez que lo ocupemos). Recuerden que después de modificarlo deben recargar el logger dentro del Asterisk CLI

*CLI> logger reload

Y por último pueden descargar/cargar el módulo que da problemas en memoria. Este es un ejemplo del módulo de SIP:

amx*CLI> module unload chan_sip.so
Unloaded chan_sip.so
== Unregistered channel type 'SIP'
== Unregistered custom function SIPCHANINFO
== Unregistered custom function SIPPEER
== Unregistered custom function SIP_HEADER
== Unregistered custom function CHECKSIPDOMAIN
== Unregistered application 'SIPDtmfMode'
== Unregistered application 'SIPAddHeader'
== Unregistered application 'SIPRemoveHeader'
== Unregistered RTP glue 'SIP'
== Manager unregistered action SIPpeers
== Manager unregistered action SIPshowpeer
== Manager unregistered action SIPqualifypeer
== Manager unregistered action SIPshowregistry
== Manager unregistered action SIPnotify
amx*CLI> module load chan_sip.so
Loaded chan_sip.so
SIP channel loading...
== Parsing '/etc/asterisk/sip.conf': == Found
== Parsing '/etc/asterisk/sip_general_additional.conf': == Found
== Parsing '/etc/asterisk/sip_general_custom.conf': == Found
== Parsing '/etc/asterisk/sip_nat.conf': == Found
== Parsing '/etc/asterisk/sip_registrations_custom.conf': == Found
== Parsing '/etc/asterisk/sip_registrations.conf': == Found
== Parsing '/etc/asterisk/sip_custom.conf': == Found
== Parsing '/etc/asterisk/sip_additional.conf': == Found
== Parsing '/etc/asterisk/sip_custom_post.conf': == Found
== Parsing '/etc/asterisk/users.conf': == Found
[2012-03-20 01:48:54] WARNING[4896]: chan_sip.c:28479 reload_config: No valid transports available, falling back to 'udp
'.
== SIP Listening on 0.0.0.0:5060
== Using SIP TOS bits 96
== Using SIP CoS mark 4

En este otro ejemplo puede notarse como el módulo SIP arroja un WARNING. Eso es un típico caso de que algo en mi configuración no está 100% bien, por lo que conviene revisarlo.

Este paso de quitar/cargar el módulo en memoria resulta muy adecuado porque la información que arroja ese módulo no se pierde entre toda la demás al momento de hacer un reload. Fíjense en los detalles y pregúntense que quiso decir el CLI cuando les dió un warning o error. Los mensajes suelen ser bastante explícitos, solo depende de ustedes interpretarlos.

¡Suerte!

Christian Cabrera

Soy ingeniero en comunicaciones con especial interés en el área de voz sobre IP y tecnologías sobre información. He usado Asterisk de manera diaria desde hace más de 18 años. En el 2011 co-fundé Enlaza Comunicaciones, una empresa que se especializa en brindar servicios profesionales de consultoría sobre voz sobre IP basadas en Asterisk, así como servicios de interpretación simultánea y traducción.