Asterisk y 3PCC, vía SIP Notify (Hold, Talk)

Buenas,
Hacía tiempo que no escribíamos, como siempre se suele decir, no es que hayamos estado parados, de hecho, todo lo contrario …
En esta ocasión os presentamos un parche propio de la casa para permitir cierto control de la llamada desde el AMI, para canales SIP y terminales que lo soporten.
SIP Call-Flow Hold&Talk
Antes, un poco de historia/background info:
Los que soléis/solemos trabajar con el AMI somos muchas veces muy entusiastas (“se puede hacer todo vía AMI”), en la práctica, desde AMI muchas veces se comprueba/monitoriza como está todo, se añaden miembros a colas, se ejecutan reloads, etc . Pero sobre el control en si de la llamada estamos un poco limitados: Podemos colgar una llamada, podemos transferirla (Redirect, Atxfer, Bridge) pero no podemos ni responderla ni ponerla en espera de forma limpia.
Para el primer caso: “Responder una llamada”, parece lógico que no se pueda hacer, si una llamada está timbrando en un SIP UA, no existe mecanismo “oficioso” para forzarle a contestar, como muchas veces dice Olle Johansson en SIP el UA “is the King”, salvo cabeceras de auto-answer y tal (pero claro, ya hemos lanzado el INVITE). Para el segundo caso (poner en hold), si que se podría gestionar algo con INVITEs lanzados desde el UAS (Asterisk) sendonly/recvonly y tal. Pero tampoco es un escenario fácil.

Siguiendo con este hilo, la gente de Broadsoft tiene una propuesta de especificación 3PCC (Third Party Call Control) basada en NOTIFY’s en el diálogo, con Event: Hold y Event: Talk. Esta especificación parece que ha sido discutida por la comunidad (Ejemplo: Lista IETF SIP Implementors(comentarios no muy positivos al respecto) y también implementada, al menos por ciertos fabricantes como SNOM, Yealink y seguramente varios mas.
Sin querer entrar en el debate si es la mejor forma de hacer las cosas, a nivel de gestión y estándares por un lado y a nivel técnico por otro, nos limitamos a comentar lo que hemos implementado:
Al igual que muchos otros NOTIFY’s soportados por terminales (Check-SYNC para volverse a provisionar, reboot y compañía) parece claro que sería algo tan sencillo como añadirlo en sip_notify.conf y enviar desde el CLI o AMI “sip notify XXXXX hold” por ejemplo. Sin embargo, esa opción no es posible, ya que esos NOTIFYs que se envían son totalmente fuera del diálogo, de hecho, son un diálogo completamente nuevo (From,To,Call-ID).

Dicho esto, lo que hemos hecho es un pequeño parche que permite enviar dichos NOTIFYs sobre un diálogo en curso, respetando el flujo normal (o al menos, el esperado) de acontecimientos (CSEQ, entre otros). Lo interesante de este mecanismo es que realmente es poco agresivo, ya que cuando lo reciba, el terminal es quien envía el INVITE para poner en hold, el servidor le responde y tal, vamos, que es exactamente igual que si el usuario físicamente pulsa la tecla de Hold, con lo que no hay que tener tracking de estados ni nada similar.

En entornos tipo Callcenter, cuando no se dispone de softphone (por la razón X que sea), es un mecanismo bastante interesante, ya que es mas o menos sencillo implementar un interfaz totalmente independiente del terminal, donde el agente pueda contestar o retener la llamada, sin tener que tenerle todo el rato en línea, o desconectar/reconectar canales y las temidas consecuencias en los CDR’s y los parsers de turno de cada uno.

Nada más, lo tenéis desgargable aquí (SIPNotifyChan_AMI_Event.patch) (Patch de Kaian), añade código nuevo, así que debería aplicarse bien en cualquier 1.8.x reciente.

Para probarlo, una vez aplicado:

telnet localhost 5038
Action: Login
Username: miuser
Secret: mipass

Action: SIPnotifychan
Channel: SIP/XXXXXX
Event: hold

Action: SIPnotifychan
Channel: SIP/XXXXXX
Event: talk

El evento hold retiene una llamada activa, el evento talk la recupera pero también vale para responder una entrante. Comprobado que funciona bien con terminales Yealink T20P,T26P y T28P (no hemos comprobado más), si alguno se anima, bienvenido sea.
Lo hemos probado de forma preliminar y no parece que se rompa nada, pero como siempre, si lo utilizáis, probadlo bien y tal.

Te ha gustado? Compartelo:
  • Print
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • Meneame
  • Twitter

Recibiendo datos de la calidad del audio tras una llamada

A menudo (o siempre) es interesante recibir datos sobre la calidad de audio de una llamada que ha procesado nuestro Asterisk. Hablamos del Jitter, PacketLoss, MOS (Mean Opinion Score)… Aunque hay otras opciones como utilizar los RTCP Stats de Asterisk (Mejorado a partir de 1.6, pero en desuso) donde se establecen variables de canal con los datos de la calidad de audio de la llamada, hoy vamos a probar las opciones que nos dan los propios terminales SIP (¡Inteligencia en los terminales!).

Las últimas versiones del firmware de Cisco para sus terminales Spa5xx (+7.4.7), nos permiten configurar un parámetro con el que podremos enviar toda la información relativa a la calidad del audio a un servidor tras finalizar una llamada (Terminales Snom con firmware +v8 parece que también lo soportan, pero no lo hemos probado). Se configura desde la propia web de forma muy sencilla:

Lo que hace el terminal en si es, enviar un mensaje SIP PUBLISH al servidor definido (P.Ej: collector@192.168.1.1:5060) conteniendo en el body datos relacionados de la llamada y la calidad de ésta.
Estos eventos están definidos en el RFC6035: Session Initiation Protocol Event Package for Voice Quality Reporting. Por si queréis echar un vistazo… ;P

Un ejemplo del mensaje que envía el terminal:

PUBLISH sip:collector@10.1.100.190:7060 SIP/2.0.
Via: SIP/2.0/UDP 10.10.0.180:5060;branch=z9hG4bK-e20d9c33.
From: <sip:terminalSIP@10.1.100.190>;tag=f23bbd323541b235.
To: <sip:terminalSIP@10.1.100.190>.
Call-ID: a01e12b6-6eb5ba81@10.10.0.180.
CSeq: 64175 PUBLISH.
Max-Forwards: 70.
Contact: <sip:terminalSIP@10.10.0.180:5060>.
Accept: application/sdp, message/sipfrag.
Event: vq-rtcpxr.
User-Agent: Cisco/SPA504G-7.4.7.
Content-Length: 802.
Content-Type: application/vq-rtcpxr.
.
VQSessionReport: CallTerm.
LocalMetrics:.
Timestamps:START=2011-5-11T11:20:18Z STOP=2011-5-11T11:20:19Z.
SessionDesc:PT=8 PD=PCMA SR=8000 FD=20 FO=8 FPP=10 PPS=100 PLC=3 SSUP=off.
CallID: e850c0fe-1e19aa0f@10.10.0.180.
FromID: <sip:terminalSIP@10.10.0.180:5060>.
ToID: <sip:5998@10.1.100.190:5060>.
OrigID: <sip:terminalSIP@10.10.0.180:5060>.
LocalAddr: IP=10.10.0.180 PORT=16824 SSRC=467580294.
LocalMAC: 00:02:fd:ff:d3:5a.
RemoteAddr: IP=10.1.100.190 PORT=13914 SSRC=510.
RemoteMAC: 0.
JitterBuffer:JBA=3 JBR=15 JBN=171 JBM=171 JBX=300.
PacketLoss:NLR=0 JDR=255.
BurstGapLoss:BLD=0 BD=0 GLD=0 GD=0 GMIN=16.
Delay:RTD=0 ESD=177 SOWD=88.
Signal:RERL=127.
QualityEst:RLQ=22 RCQ=20 MOSLQ=1.2 MOSCQ=1.2 QoEEstAlg=P.564.

DialogID:e850c0fe-1e19aa0f@10.10.0.180;to-tag=as0df6f540;from-tag=ea2ec326d50586bo0.

Si os fijáis, el servidor que recibe este PUBLISH está escuchando en el 5070 mientras la señalización de las llamadas (SIP) está en el puerto 5060. Sí, mientras Asterisk gestiona las llamadas necesitamos un OpenSIPS/Kamailio para gestionar estos PUBLISH.
¿Por qué?
Porque Asterisk hasta la versión 1.8 (quizá alguna versión de 1.6?¿) ni siquiera soportaba mensajes del tipo PUBLISH y a partir de la 1.8 los soporta pero no para estos eventos concretos (vq-rtcpxr). La respuesta de un Asterisk: :(

SIP/2.0 489 Bad Event.
Via: SIP/2.0/UDP 10.10.0.177:5061;branch=z9hG4bK-aea9a42c;received=10.10.0.177.
From: ;tag=11636c9b167e05fa.
To: ;tag=as0d04d7f8.
Call-ID: ae68d5ef-aadd8cb6@10.10.0.177.
CSeq: 1316 PUBLISH.
Server: "Irontec IVOZ".
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH.
Supported: replaces, timer.
Content-Length: 0.

A lo que vamos… vamos a configurar un OpenSIPS/Kamailio para recibir estos mensajes y hacer después con ellos lo que creamos oportuno (guardarlo en BBDD, ejecutar un script…).
No vamos a explicar como instalar el software ya que hay multitud de ‘HowTo’-s disponibles en la red. Vamos directamente a lo que nos interesa, el fichero de configuración. En este caso se ha utilizado OpenSIPS pero con Kamailio debería ser muy parecido si no igual. Es una instalación básica sin ningún módulo extra, ya que en este caso lo único que haremos será recibir los datos, ejecutar un script y responder con un OK.
Dialplan” de opensips.cfg:

####### Routing Logic ########

route{

if (!mf_process_maxfwd_header(“10″)) {

sl_send_reply(“483″,”Too Many Hops”);
exit;

}

if (!is_method(“PUBLISH”))  ## Solo gestionaremos PUBLISH
{

sl_send_reply(“503″,”Not here please”);
exit;

}
if (!uri==myself)
{

sl_send_reply(“503″,”SIP Publish ok, but please use our domain”);
exit;

}
if (is_method(“PUBLISH”))
{

if (!$(hdr(Event)[-1]) == “vq-rtcpxr”)  ## Solo gestionamos este evento concreto. Audio quality
{

sl_send_reply(“503″,”Not here please”);
exit;

}

xlog(“EVENT: $(hdr(Event)[-1])”);   ##Un poco de log…
xlog(“Got a PUBLISH: $rb”);

exec_avp(“/root/testing/test.sh ‘$rb’”);  ##Ejecutamos un Script pasándole como variable el body del PUBLISH recibido. También se puede utilizar la función exec_msg
sl_send_reply(“200″, “Thanks for this stats”);  ##Respondemos con un 200
exit;

}

}

Como se puede ver en los comentarios del código anterior, es posible utilizar, además de ‘exec_avp’, la función ‘exec_msg’. La diferencia es que, en un caso se procesa la salida del comando (exec_avp) y en el otro no (exec_msg). Detalle importante: la variable ‘$rb’ (reference to message body) tiene que pasarse al script entre comillas, porque el cuerpo del mensaje contiene caracteres especiales y necesitamos que nuestro script los pueda interpretar. Más info al respecto aquí y aquí.

¿Que podemos hacer en este script externo? Pues, todo lo que necesitemos/queramos y nuestra imaginación nos permita. Por ejemplo, sacar informes de calidad de audio de llamadas representando estos datos en gráficas creadas con RRDtool…

Happy VoIP hacking !!! ;P

Te ha gustado? Compartelo:
  • Print
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • Meneame
  • Twitter

Queuerules en Asterisk 1.8

Queuerules en Asterisk 1.8

Aunque la funcionalidad de queuerules se aplicó en la versión de asterisk 1.6, como tantos otros, nosotros hemos empezado a utilizar las nuevas posibilidades que nos encontramos al migrar desde asterisk 1.4 (en nuestro caso 1.4-rsp) a la nueva versión 1.8.

Hoy en día cuando configuramos colas, estas están compuestas por miembros que las atienden. En las colas estos miembros están ordenados para atender llamadas y asterisk decide a quien debe de enviarle la llamada. Esta decisión la toma en base a unos parámetros como la estrategia, o la prioridad de los miembros en la cola. Para el caso que nos atañe, lo que nos interesa es la prioridad o penalty.

Gracias a la prioridad, podemos priorizar quien atenderá las llamadas. La forma común de comportarse una cola sería la siguiente:

Primero atenderán la llamada loa miembros que estén con prioridad “1”, si no hay nadie disponible con esta prioridad, atendrán la llamada los miembros con prioridad “2”, si no los de prioridad “3”, y así sucesivamente.

El problema está en colas con muchas llamadas. En este caso casi siempre los miembros con prioridad 1 están ocupados con lo que saltan a los miembros con prioridad 2. Si queremos que no les entre la llamada a los miembros con prioridad 2 hasta pasados X segundos, solo podíamos dirigirlos hacia otras colas con otros miembros con distinta prioridad, pero esto hace que la persona que ha entrado en la cola pierda su puesto en ella, ya que le mandamos a otra cola.

Pero ahora con podemos hacer que esa prioridad máxima y mínima de atención en la cola varíe en el transcurso de la llamada. Para esto tenemos las reglas de cambio de prioridad definidas en “queuerules.conf” y las variables de canal QUEUE_MIN_PENALTY QUEUE_MAX_PENALTY. Las variables definen la prioridad máxima y mínima de los agentes que atenderán la llamada y esta regla se puede aplicar de dos formas, en la opción “rule” de la aplicación Queue o bien en la opción de cola “defaultrule”.

Queuerules.conf

En este archivo de configuración podemos crear reglas para modificar las prioridades máxima y mínima que atenderán en la cola. Solo los miembros que estén entre estas prioridades máxima y mínima podrán recibir llamadas de la cola. Estas reglas se definen de la siguiente manera en queuerules.conf

; sintaxis
; penaltychange => ,[,cambio absoluto o relativo de QUEUE_MIN_PENALTY]
[myrule]
penaltychange => 30,+1 ; después de 30 segundos, incrementa QUEUE_MAX_PENALTY en 1 y deja QUEUE_MIN_PENALTY igual .
penaltychange => 45,5,2; después de 45 segundos, pone QUEUE_MAX_PENALTY a 5 y QUEUE_MIN_PENALTY lo pone a 2.
penaltychange => 75,,1; después de 30 segundos, deja QUEUE_MAX_PENALTY como estaba y QUEUE_MIN_PENALTY lo pone a 1.

Un ejemplo lógico sería:

Creamos una cola

[COLA1]
musicclass=default
strategy=rrmemory
joinempty=no
leavewhenempty=yes
ringinuse=no
defaultrule=miembros-prio

member => SIP/0000FFFF0001,0,Miembro 1 ; Prioridad 1
member => SIP/0000FFFF0002,1,Miembro 2 ; Prioridad 2
member => SIP/0000FFFF0003,2,Miembro 3 ; Prioridad 3

Tenemos como regla de prioridades en queuerules.conf lo siguiente:

[miembros-prio]
penaltychange => 30,+1
penaltychange => 60,+1

En el dialpan tendríamos esto:

[entrantes]
exten => X.,1,NoOp(Llamada entrante de ${CALLERID(num)})
exten => X.,n,Set(QUEUE_MIN_PENALTY=1)
exten => X.,n,Set(QUEUE_MAX_PENALTY=1)
;Queue(queuename[,options[,URL[,announceoverride[,timeout[,AGI[,macro[,gosub[,rule[,position]]]]]]]]]) con lo que se podría aplicarse la “rule” miembros-prio en esta aplicación ejem: exten => X.,n,Queue(COLA1,,,,,,,,miembros-prio). Como en queues.conf ya la hemos definido como regla por defecto, no hace falta.
exten => X.,n,Queue(COLA1)

Esto hará que primero busque a los miembros con prioridad 1, si están ocupados no busca a miembros con mayor prioridad hasta que pase 30 segundos que es cuando la regla que hemos definido aumenta el QUEUE_MAX_PENALTY a 2. En este momento buscará miembros con prioridad 2 y si están también ocupados no buscará los de más prioridad hasta pasados otros 30 segundos como está definido en la regla miembros-prio.

Te ha gustado? Compartelo:
  • Print
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • Meneame
  • Twitter

TLS+SRTP en Asterisk 1.8 (Especial Cisco SPA5xx)

Volvemos a la carga con un pequeño post sobre como configurar otra de las nuevas features que nos trae Asterisk 1.8: TLS y SRTP, audio (y video) cifrado y seguro.
Estos tests se han realizado con terminales Cisco SPA5XX, que supone tener que aplicar un pequeño parche en el código de Asterisk (luego veremos el porque), pero funciona exactamente igual para terminales Snom y softphones como Blink
La parte de configuración se explicará bastante rápido, ya que está explicado en varios sitios en la web.

Empezamos:
1. Es necesario compilar la librería libSRTP para que Asterisk tenga el soporte SRTP.

wget http://srtp.sourceforge.net/srtp-1.4.2.tgz
tar zxvf srtp-1.4.2.tgz
cd srtp/
CFLAGS="-Wall -O4 -fexpensive-optimizations -funroll-loops -fPIC" ./configure
make && make install

2. Descargamos y Compilamos Asterisk: (Para este Post se utiliza la versión 1.8.2.3)

svn co http://svn.asterisk.org/svn/asterisk/tags/1.8.2.3/ asterisk18
cd asterisk18
./configure
make menuselect (nos aseguramos de que esté res_srtp activado en 'Resource Modules')

**Ahora es cuando tenemos que aplicar el parche anteriormente mencionado**
¿Porque? Es necesario parchear el código porque los terminales SPA5xx envían dos líneas con el atributo crypto, tal que:

a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:Ud154Hz42jLai6YI7RBcKtctTHBzIKjiHM6nGD36.
a=crypto:2 AES_CM_128_HMAC_SHA1_80 inline:Ud154Hz42jLai6YI7RBcKtctTHBzIKjiHM6nGD36.

y Asterisk no es capaz de negociar cual de los métodos (AES_32 o AES_80) se va a utilizar para la encriptación. De hecho, sólo escoge el primero y como podéis ver, los Cisco envían primero el AES_32.
Aquí está el problema. Asterisk es capaz de manejar ambos tipos, pero sólo ofrece uno de ellos, el AES_80. Por tanto, tenemos que parchear el código para que Asterisk ofrezca en la señalización encriptación AES_32. Si no, se cifrará el Audio en las dos patas con un tipo diferente y nos quedamos sin audio y con un mensaje eterno (30 por Seg.) en el CLI:

WARNING[25205]: res_srtp.c:338 ast_srtp_unprotect: SRTP unprotect: authentication failure

Más info al respecto en el Bugtracker de Digium
Un poco de SIP para ver “claro” el problema (primer INVITE e INVITE de Asterisk al destino):

INVITE sip:200@10.10.0.165 SIP/2.0.
From: ;tag=630e30c1d5621880o3.
To: "200" .
m=audio 16890 RTP/SAVP 8 0 9 18.
a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:hE+4XPMbPaF9/XEgIek7rUJiqoTEpLGZ1YXNiJhS.
a=crypto:2 AES_CM_128_HMAC_SHA1_80 inline:hE+4XPMbPaF9/XEgIek7rUJiqoTEpLGZ1YXNiJhS.

INVITE sip:200@10.10.0.177:5063 SIP/2.0.
From: "100" ;tag=as72caceda.
To: .
Contact: .
User-Agent: Asterisk PBX 1.8.2.3.
Remote-Party-ID: "100" ;party=calling;privacy=off;screen=no.
m=audio 12202 RTP/SAVP 8.
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:5uWtfxfK0vE90lTrgLTr83bRWTL2nCEFJ6NlXWjq.

El parche es bien simple:

--- channels/sip/sdp_crypto.c 2010-06-08 07:29:08.708826000 +0200
+++ channels/sip/sdp_crypto.c 2011-02-24 17:37:00.514711568 +0100
@@ -287,7 +287,8 @@
int sdp_crypto_offer(struct sdp_crypto *p)
{
char crypto_buf[128];
- const char *crypto_suite = "AES_CM_128_HMAC_SHA1_80"; /* Crypto offer */
+ //const char *crypto_suite = "AES_CM_128_HMAC_SHA1_80"; /* Crypto offer */
+ const char *crypto_suite = "AES_CM_128_HMAC_SHA1_32"; /* Crypto offer */

if (p->a_crypto) {
ast_free(p->a_crypto);

Aplicamos el parche (lo hemos nombrado como sdp_crypto.patch):

patch -p0 < sdp_crypto.patch (suponiendo que estamos en /usr/src/asterisk18 y tenemos el parche en la misma carpeta)

Asterisk is patched!!! :P
Ya podemos compilar e instalar:

make && make install

3. Configuración (tanto para TLS como para SRTP)
**TLS**
-Primero nos generamos una clave pública y otra privada, las fusionamos en un único fichero y la guardamos en algún sitio conocido.
Hay formas mucho mejores y elegantes de hacerlo (léeme), pero esto sólo es para testing! :P

openssl genrsa 1024 > host.key
openssl req -new -x509 -nodes -sha1 -days 365 -key host.key > host.cert
cat host.cert host.key > asterisk.pem
mv asterisk.pem /etc/asterisk/keys/

-Configuramos sip.conf para poder utilizar TLS:

tlsenable=yes
tlsbindaddr=0.0.0.0
tlscertfile=/etc/asterisk/keys/asterisk.pem

-Configuramos los peers para que trabajen con TLS. Tanto en realtime como en raw en sip.conf hay que añadir:

transport=tls (por defecto es UDP)

-Configuramos nuestro SPA5XX para que utilice TLS:

Ya tenemos señalización segura entre Asterisk y los terminales!! ;P
Para asegurarnos capturamos en el puerto 5061 y no vemos “nada”:

....J...F..Mg|.L^
...E}.....A...d.|.~...... l..i9.j,..q"..............&./....5................0..~0...................0...*.H........0..1.0...U....ES1.0...U....Vizcaya1.0...U....Erandio1.0...U.
..Irontec1.0...U....VozIP1.0...U....Irontec1 0...*.H........vozip@irontec.com0...110215125446Z..210212125446Z0..1.0...U....ES1.0...U....Vizcaya1.0...U....Erandio1.0...U.
..Irontec1.0...U....VozIP1.0...U....Irontec1 0...*.H........vozip@irontec.com0..0...*.H............0........>.S.51...bND.J..Q..O.).-t.."~x..g&^t....E.*..@..n.jF...v.t.<....Zf...%Y.......[...[....HE.e....9..8...qc..|(...P.....*.c4>.V..........0..0...U.........En?.0.%.^......
.0....U.#...0.......En?.0.%.^......
.......0..1.0...U....ES1.0...U....Vizcaya1.0...U....Erandio1.0...U.
..Irontec1.0...U....VozIP1.0...U....Irontec1 0...*.H........vozip@irontec.com...........0...U....0....0...*.H............T.-F....R..2%.....T......=9.ye.z..6.0............i...O;.../s..e.........S.6.31......!iT......N....]........>XNt....Z...MHKH3...K.........

**SRTP**
-Para configurar SRTP tenemos que poner la directiva ‘encryption’ en los peers (ya sean realtime o en sip.conf)

encryption=yes

-En los SPA5XX hay que tocar 3 valores. Esto es configurable al menos, desde la versión 7.4.3 del firmware (OJO! que se aplica para todas las líneas configuradas):
+SRTP Method: s-descriptor

+Secure Call Serv: yes

+Secure Call Setting: yes

Voilá! Ya tenemos SRTP configurado!
DETALLE: No hay modo opcional de SRTP para Asterisk, es decir, si está encryption activado en el peer no aceptará audio no cifrado y al contrario. En los terminales en cambio, si está el cifrado configurado, pero no el peer como tal, las llamadas entrantes se establecerán sin problemas. No así, las salientes, porque el terminal hemos dicho que tenía SRTP activo y para Asterisk no. En los Snom se puede utilizar también el modo ‘Optional’ para el SRTP (envía dos atributos m=audio con y sin SRTP), pero Asterisk no sabe manejar estos SDP… :S

4. Pruebas
Para probar todo esto lo más fácil es capturar tráfico en la red y después verificar con WireShark, OmniPeek o cualquier otro software si vemos la señalización en claro y si podemos escuchar las conversaciones.
En los test realizados en nuestro lab, nos encontramos con un Warning (no siempre) en el CLI, pero en principio todo funciona como debe.

WARNING[25205]: res_srtp.c:338 ast_srtp_unprotect: SRTP unprotect: authentication failure

Estamos debuggeando este último punto para ver que puede estar provocándolo…

**Curiosidad**
Los CiscoSPA5XX cuando están con SRTP activado, reproducen una especie de “beep” tres veces al principio de la conversación y muestran en pantalla un $ como símbolo de conversación encriptada. Un ejemplo:

Al final ha quedado un post un tanto largo… pero bueno, esperemos que sirva a alguien! ;P
Como siempre, cualquier duda/consulta/crítica será bienvenida.

Un saludo!

Te ha gustado? Compartelo:
  • Print
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • Meneame
  • Twitter

Algunas experiencias con Asterisk 1.8.x

Muy buenas,
Como muchos sabéis, el tema de Asterisk 1.8 está todavía calentando motores, aunque al contrario que la serie 1.6 que no fue del todo aceptada por la comunidad, parece que está vez, tanto por features como por estabilidad / ciclo de desarrollo, la gente se lo está planteando.

Por nuestra parte, todas las instalaciones y proyectos que realizamos los basamos (entre otros temas) en Asterisk RSP , que funciona a las mil maravillas.

En las instalaciones grandes, hay muchos puntos que deben ser controlados al milímetro, para que salga a la perfección, pero a parte de “funcionar”, la preocupación obvia es la estabilidad. Así que hemos decidido ir publicando un poco nuestros pasos y experiencias, que estamos teniendo en “pequeños” proyectos, que no utilizan todo Asterisk en sí o no son permanentes.

Por el momento, hemos utilizado Asterisk 1.8 en dos proyectos:

La experiencia ha sido muy positiva, no hemos tenido ningún problema especial. Eso si, no utilizábamos ni real time, ni CDR de transferidas, ni pickup, ni mil BLFs, ni nada típico de PBX …

Lo que hemos utilizado en el primer caso ha sido:

  • Recepción vía ITSP (SIP) de varios números (vinculados a 900).
  • AGI’s simples para guardar / checkear intervalos, etc …
  • En total, se recibieron 41.300 llamadas aprox en apenas 3 horas.

En el segundo caso:

  • Recepción vía TDM, de 16 PRIs (EuroISDN).
  • Grabación concurrente simúltaneas de todas las llamadas (utilizando Ramdisk a tope).
  • (luego todo un tema de ffmpeg/sox del mágico Fabrice Bellard, pero no es de Asterisk ;) )

Como véis, la experiencia no es que sea totalmente concluyente y todos a migrar a 1.8, pero es un primer pasito, para ir viendo datos de lo que se puede hacer. La verdad, es que ambos casos eran para eventos muy concretos y nos la jugamos un poco, pero todo salió bien, con fé ciega ;) . Las funciones o módulos involucrados no son numerosos, pero la cantidad de llamadas procesadas sí. Está claro que es cuando mezclas muchas partes de Asterisk cuando puedes tener una race condition, un memory leak perdido o algo díficil de detectar, pero bueno, vamos viendo luz :)

De cara a ir migrando nuestra solución IVOZ , e ir haciendo proyectos de IP PBX Corporativo o Callcenter, todavía queda mucho (CEL, TLS/SRTP, …), pero poco a poco iremos testeando cada parte, para ver si podemos llegar a tener ciertas certezas:)

Te ha gustado? Compartelo:
  • Print
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • Meneame
  • Twitter

Nuevas funcionalidades de Asterisk 1.8: Update de CallerID

La versión 1.8 de Asterisk ha aportado nuevas features interesantes, como por ejemplo, CEL, SRTP, soporte para fax, calendarios compartidos, soporte IPv6…

En este caso nos vamos a centrar en una feature simple pero que los clientes que provienen de centralitas comerciales suelen echar en falta. La actualización del CLID en transferencias. Hablamos en todo momento de transferencias atendidas y realizadas mediante REFER-s, es decir, transferencias a través del propio terminal y no a través de las features nativas de Asterisk.
Para que funcione, hay que configurar un par de cosas en sip.conf:

  • Si queremos utilizar la cabecera SIP Remote-Party-ID:
    sendrpid=yes o sendrpid=rpid (es lo mismo)
  • Si queremos utilizar la cabecera SIP P-Asserted-Identity:
    sendrpid=pai
  • Obligatoriamente:
    directmedia=update

Es necesario configurar directmedia a update (además del sendrpid) para que Asterisk envíe mensajes SIP de tipo UPDATE ya que si envía INVITE-s (re-invites para decir que el audio está en otro punto) recibimos un mensaje 500 (Internal Server Error) por parte del terminal de destino final. Es decir, cuando se hace el REFER Asterisk le envía un INVITE al destino final diciendo que el audio lo tiene él, para acto seguido enviarle otro INVITE (CSeq+1) diciendo que el audio está en otro terminal (PtP audio). A este segundo INVITE es al que el terminal responde con un 500.
Espero que en la siguiente imagen se entienda mejor:

Ahora la captura SIP completa con “directmedia=yes” & “sendrpid=yes” donde:

    Asterisk => 10.10.0.165
    C phone (300) => 10.10.0.142
    B phone (200) => 10.10.0.177
    A phone (100) => 10.10.0.167

Esta vez, la captura SIP completa con Ngrep y “directmedia=update” & “sendrpid=yes/pai” donde:

    Asterisk => 10.10.0.165
    C phone (300) => 10.10.0.142
    B phone (200) => 10.10.0.177
    A phone (100) => 10.10.0.167

No me es posible presentar la captura con una imagen como la superior (el software omnipeek no “ve” los UPDATE-s), así que os dejo unas trazas en los siguientes enlaces:
Traza SIP con sendrpid=yes
Traza SIP con sendrpid=pai

Después de tanta traza SIP, comentar también que no sirve cualquier terminal (o mejor dicho cualquier firmware¿?), tiene que aceptar UPDATEs. Con los Cisco SPA5xx funciona a la perfección. Los Linksys SPA9xx no aceptan Updates y algunos Snom y Aastra tampoco… aunque tampoco me he puesto a jugar demasiado con la configuración de estos últimos.

Como se ha comentado en la entradilla del post, aquí se habla en todo momento de transferencias atendidas. En el caso de transferencias semi-atendidas (xfer->dial->xfer sin haber establecido la segunda llamada) funciona a la perfección en cualquier caso. Me explico, utilicemos audio PtP o no, bien con UPDATEs, bien con INVITEs, Asterisk envía un UPDATE para actualizar los datos de sesión cuando la segunda llamada no ha sido establecida, por lo que el CLID se actualiza sin problemas. Las transferencias ciegas también funcionan correctamente (en la versión 1.8.0 había un Bug que se solucionó más tarde).

Espero haberme explicado bien. Estamos aquí para cualquier duda/sugerencia o corrección.

Un saludo.

Te ha gustado? Compartelo:
  • Print
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • Meneame
  • Twitter

Nuevas funcionalidades de Callcenter en Asterisk-ES-RSP

Tal y como comentábamos en su inicio, Asterisk-ES-RSP continua aportando su granito de arena corrigiendo bugs que reporta la comunidad e implementando funcionalidades interesantes, inexistentes en la versión base de esta release.

Para aquellos que aún no lo sepáis, el código fuente de Asterisk se descarga ahora del repositorio de Digium y después son aplicados los parches creados por el grupo. Todo esto se lleva a cabo a través del autopatcher. Después de la descarga del código y la aplicación de parches, la instalación de Asterisk no varía con respecto al método habitual.

Recién salidos del horno, comentamos tres nuevos parches ya commiteados y otros dos a la espera de ser probados por todo aquel que esté interesado en ellos. Esta vez nos hemos centrado en la cara más ‘callcenter’ de Asterisk. Los últimos parches commiteados son los siguientes:

- Bugfix: Solución del segfault generado al hacer una transferencia en asterisk-es-rsp desde una sala de conferencias.

Una pequeña modificación en el parche chan_sip-ironxfers.patch evita los segmentation faults en este escenario.

- Feature: Backport del soporte de shared_lastcall para colas.

Seguramente más de uno de vosotros ha tenido problemas al tener un agente atendiendo varias colas  con diferente tiempo administrativo. Asterisk consulta el tiempo de la última llamada atendida por el agente y verifica si éste es superior al tiempo administrativo (wrapuptime) de la cola que se tiene que atender ahora, sin tener en cuenta el wrapuptime de la cola donde fue atendida.

Desde las versiones más recientes de Asterisk, nos hemos traído esta funcionalidad que hace cuadrar los tiempos administrativos de los agentes en este escenario.

Esta funcionalidad hace que la disponibilidad del agente sea calculada en función del tiempo administrativo de la última cola atendida y no aquel de la cola que se quiere atender.

1 Point!

- Feature: Backport de la opción ‘R’ de la aplicación ‘Queue’.

Para aquellos que buscáis el comportamiento de los callcenters tradicionales, esta funcionalidad hace que el llamante escuche tono de llamada en lugar de música en espera cuando el terminal del agente está sonando.

Ya podéis disfrutar de estás funcionalidades siguiendo estas instrucciones.

Recordad que el branch a descargar sería el siguiente: http://asterisk-es-rsp.irontec.com/svn/asterisk-es-rsp/branches/asterisk/1.4.24.1/autopatcher/

A continuación listamos los nuevos parches subidos al team doktore y que están siendo probados  antes de ser commiteados:

- Feature: Backport de la función QUEUE_MEMBER.

Nos gusta saber si hay agentes disponibles antes de meter la llamada en cola. Por ello hemos añadido esta funcionalidad. Si conocemos la disponibilidad de los agentes antes de entrar en cola, podemos mandar la llamada a otra cola donde sí pueda ser atendida inmediatamente y así mejorar el nivel de servicio. Por otra parte, si sabemos antes de entrar en la cola que todos los agentes están ocupados podemos advertírselo al llamante con una locución antes de ejecutar la aplicación ‘Queue’.

Como aditivo a la función original, este parche hace uso de la funcionalidad shared_lastcall comentada anteriormente para tener en cuenta los escenarios de agentes atendiendo múltiples colas.

- Feature: Mostrar el ‘state_interface’ del miembro de la cola al hacer un ‘queue show’ desde el CLI.

Esteroides para complementar el primer parche de asterisk-rsp (app_queue-state_interface.patch). El nuevo parche (app_queue-state_interface-queueshow.patch) nos permite ver desde consola el interfaz de estado de un miembro definido como Local/ y así conocer el terminal desde donde está atendiendo las llamadas. Supongo que aquellos que trabajéis con grandes callcenters lo agradeceréis!

Para aquellos que queráis probar estos dos últimos parches podéis descargaros este autopatcher modificado que los aplica y después instalar Asterisk  del mismo modo que siempre.

Esto es todo! Felicidades a asterisk-es-rsp y gracias por vuestro feedback y vuestros bug reports!

Te ha gustado? Compartelo:
  • Print
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • Meneame
  • Twitter

BYE sip:AstriCon209…

Por fin e conseguido algo de Internet (en Las Vegas mucho casino pero poco WiFi :( ) y puedo comentar lo que viví durante tres días en el AstriCon.

4013543198_dd22dc90cb_bEn una palabra (en inglés): awesome! Creo que no podía haber estado mejor. Me lo he pasado en grande y he tenido la ocasión de conocer a gente muy interesante y de poder intercambiar experiencias con otros tantos AstriFrikis.

El plato fuerte del AstriCon suelen ser las charlas y así ha sido éste año. No obstante, éste año no han ido tan ligadas al lado técnico y he tenido la ocasión de asistir a charlas extrañamente interesantes como por ejemplo chan_skype + Google Wave (con IAX2 de por medio) y el API de calendarios de Asterisk. He podido comprobar (con alegría) que finalmente el API de calendarios de Asterisk no es nada intrusivo con el core y se ha quedado en cuatro resource modules. Bien. También me sorprendió mucho la charla sobre OpenBTS, pero hay charlas y charlas y esa si que era de las segundas. :)

Otro de los puntos importantes era el hecho de que Asterisk cumpliera 10 años. Se armó una buena fiesta, con concurso, tarta, ¡y salchichas para todos! No faltó de nada, hasta nos dieron una medalla y un collar a lo hawaiano :)

Por último he de agradecer a todos el apoyo mostrado antes y tras el par de charlas que tuve la ocasión de dar. No me lo esperaba así ni en el mejor de mis sueños, ¡gracias!

A todo esto, ¿ya sabréis donde hay que ir de vacaciones el año que viene no? ¡Al AstriCon 2010!

Te ha gustado? Compartelo:
  • Print
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • Meneame
  • Twitter

Log en Asterisk

A menudo cuando una centralita tiene alta carga, ver la consola o los logs que genera Asterisk en /var/log/asterisk/messages no es suficiente. Porque se genera gran cantidad de información, porque al tener muchas llamadas concurrentes seguir una llamada en concreto a través de saltos en un fichero es complicado, porque a medida que integramos más y más herramientas con Asterisk las llamadas ya no se controlan o se localizan en un único punto…

Lo que vamos a intentar es tener controlado el log de todo el sistema, incluyendo Asterisk, su dialplan, los agis y cualesquira herramientas que usemos. Los objetivos son claros:

  • Tener todos los logs relevantes en un lugar unificado de tal forma que podamos seguir la pista a las llamadas o a los errores sin tener que hacer merges mentales de múltiples fuentes.
  • Tener los logs marcados y clasificados de tal forma que podamos encontrar de forma cómoda y sencilla cualquier información puntual que necesitemos.
  • Loguear todo lo que ocurre en la plataforma remotamente relacionado con el flujo de las llamadas y el correcto funcionamiento de las mismas.

En este post vamos a ver un ejemplo de cómo hacer esto con un criterio arbitrario. Se pretende que cualquira pueda adaptar este ejemplo a sus necesidades. En este ejemplo vamos a querer:

  1. Los logs generales del sistema para ver que todo es correcto. Esto es, el syslog. Deberemos filtrar cúales de los servicios del sistema que loguean al syslog queremos ver y cuáles no.
  2. Los logs relacionados con el flujo de una llamada. En este caso vamos a suponer que dialplan y agis.

Todo esto lo vamos a hacer a través del syslog del sistema y las opciones que nos brinda para filtrar y etiquetar los logs.  ¡Manos a la obra!

(más…)

Te ha gustado? Compartelo:
  • Print
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • Meneame
  • Twitter

AstriCon 2009: ¡empieza la cuenta atrás!

Ya solo quedan unas pocas horas para que de comienzo el décimo AstriCon, el AstriCon 2009 y he de confesar que algo nervioso sí que me encuentro. :) astricon-speaking-sm

Éste año se celebra la décima edición, por lo que el evento promete. Habrá charlas (como siempre) pero se ha reducido la concurrencia, ya que el año pasado había demasiadas a la vez. También tendrá su sección de expositores, donde diversas empresas expondrán sus productos y servicios. ¡Y el AstriContest!, el concurso de dialplan que éste año se realizará con terminales analógicos (are you from the past?!) y que como primer premio tendrá un terminal con Android libre. ¡Habrá que intentarlo!

Además de porque es la décima edición y porque repito (el año pasado también tuve la suerte de poder venir) éste año el AstriCon me hace especial ilusión, porque en el call for papers me aceptaron ¡dos charlas! ¡El día que recibí el mail de John Todd no pude ni dormir! Por suerte las tengo el segundo y el tercer día, así mañana puedo ir viendo cómo va el tema ;)

Aprovechando que he venido sólo (éste año Manwe no me acompaña y he venido con familia, pero se quedan en San Francisco) voy a sacar el FanBoy que hay en mi, que una vez al año no hace daño. ;)

Subiré fotos, twittearé, bloguaré, … vamos un eco-pack del Web2.0, stay tuned!

Te ha gustado? Compartelo:
  • Print
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • Meneame
  • Twitter