Enviado por admin el
La idea de este articulo es demostrar que con Asterisk 11.X es posibles enviar mensajes instantáneos desde una extensión SIP a un usuario XMPP (Jabber) y viceversa. El escenario tiene algunas limitaciones pero creo que puede ser una solución si quieren mantener el flujo de mensajes en servidores seguros y directamente gestionados por ustedes.
Para esta prueba se ha utilizado:
- Un Raspberry
- Asterisk 11.7
- Un servidor Openfire instalado en un segundo servidor
- Un Softphone X-Lite
- El cliente Spark
La idea es que cada extensión tenga un usuario XMPP configurado y que ese usuario se añada a la base de datos interna de Asterisk asociándolo con su numero de extensión. En este caso el usuario XMPP será raspberry y será asociado a la extensión 209. El segundo usuario XMPP será voztovoice.
Para empezar se crean los dos usuario en el servidor Openfire.
Luego se configura el usuario Raspberry en Asterisk.
Se modifica el archivo xmpp.conf para que quede:
[general]
debug=no
autoprune=yes
autoregister=yes
;collection_nodes=yes
;pubsub_autocreate=yes
auth_policy=accept
[raspberry]
type=client
serverhost=voztovoice.net
;pubsub_node=pubsub.voztovoice.net
username=raspberry@voztovoice.net/asterisk
secret=password
priority=1
port=5222
usetls=yes
usesasl=yes
buddy=voztovoice@voztovoice.net
;distribute_events=yes
status=available
statusmessage="Extensión 209"
timeout=5
sendtodialplan=yes
context=messages209
Los datos importantes:
- buddy=voztovoice@voztovoice.net – Se añade el usuario voztovoice a la lista de contactos
- statusmessage="Extensión 209" – Para que los usuarios XMPP sepan que el usuario raspberry está asociado a la extensión 209
- sendtodialplan=yes – Los mensajes instantáneos enviados al usuario raspberry se enviarán al dialplan
- context=messages209 – al contexto messages209 que hay que crear
Si se quiere asociar otro usuario a otra extensión, nada más crear otro bloque parecido al de [raspberry]. En el caso que se quiera asociar el usuario fulano a la extensión 210, sería:
[fulano]
type=client
serverhost=voztovoice.net
;pubsub_node=pubsub.voztovoice.net
username=fulano@voztovoice.net/asterisk
secret=password
priority=1
port=5222
usetls=yes
usesasl=yes
buddy=voztovoice@voztovoice.net
;distribute_events=yes
status=available
statusmessage="Extensión 210"
timeout=5
sendtodialplan=yes
context=messages210
Luego en la base de datos interna de Asterisk se asocia el usuario fulano a la extensión 210. Para esta prueba se crea solamente uno. Se guardan los cambios y se recarga el modulo res_xmpp.so:
asterisk -rvvvvvvvvvvvvvvv
CLI> module reload res_xmpp.so
se mira si el usuario está conectado:
CLI> xmpp show connections
Jabber Users and their status:
[raspberry] raspberry@voztovoice.net/asterisk - Connected
y que pasa con los contactos:
CLI> xmpp show buddies
Buddy: voztovoice@voztovoice.net
Se asocia el usuario raspberry a la extensión 209 en la base de datos interna de Asterisk:
asterisk -rvvvvvvvvvvvv
CLI> database put ext 209 raspberry
El usuario voztovoice todavía no está conectado. Se abre el cliente Spark y se configura el usuario voztovoice:
Se presiona el enlace Login y se espera que el cliente se conecte al servidor Openfire. El resultado será:
En la consola de Asterisk:
CLI> xmpp show buddies
Buddy: voztovoice@voztovoice.net
Resource: Spark 2.6.3
node:
version:
Google Talk capable: no
Jingle capable: no
En la pagina de administración de Openfire:
De los mensajes instantáneos entre extensiones SIP se ha hablado en este articulo; lo importante es que la parte general del sip.conf contenga estos parámetros:
accept_outofcall_message = yes
outofcall_message_context = messages
auth_message_requests = yes
Ahora se pasa al dialplan:
nano /etc/asterisk/extensions.conf
en el contexto configurado en la parte general del sip.conf para los mensajes instantáneos, se añade el siguiente bloque:
[messages]
exten => s,1,Noop(Mensaje de ${MESSAGE(from)})
same => n,Noop(Mensaje para ${MESSAGE(to)})
same => n,Noop(Texto = ${MESSAGE(body)})
same => n,Messagesend(sip:${EXTEN},${MESSAGE(from)})
same => n,Noop(Estado del mensaje ${MESSAGE_SEND_STATUS})
same => n,Hangup
Esto para los mensajes entre extensiones SIP. Luego para los mensajes recibidos por el usuario raspberry que se envian hacia la extensión 209:
[messages209]
exten => s,1,Noop(Mensaje de ${MESSAGE(from)})
same => n,Noop(Mensaje para ${MESSAGE(to)})
same => n,Noop(Texto = ${MESSAGE(body)})
same => n,Messagesend(sip:209,${MESSAGE(from)})
;same => n,Noop(Estado del mensaje ${MESSAGE_SEND_STATUS})
same => n,Hangup
Si se creara el usuario fulano, extensión 210, habría que añadir otro bloque de este tipo:
[messages210]
exten => s,1,Noop(Mensaje de ${MESSAGE(from)})
same => n,Noop(Mensaje para ${MESSAGE(to)})
same => n,Noop(Texto = ${MESSAGE(body)})
same => n,Messagesend(sip:210,${MESSAGE(from)})
;same => n,Noop(Estado del mensaje ${MESSAGE_SEND_STATUS})
same => n,Hangup
Se guardan los cambios y se actualiza el dialplan:
asterisk -rvvvvvvvvvvvv
CLI> dialplan reload
Desde el usuario configurado en Spark se envía un mensaje al usuario raspberry:
En X-Lite:
Si se intenta devolver el mensaje desde el X-Lite no pasará absolutamente nada. Se activa el debug en la consola de Asterisk:
CLI> sip set debug on
y se intenta enviar un segundo mensaje al usuario raspberry:
--- (12 headers 1 lines) ---
Receiving message!
Found peer '209' for '209' from 79.44.192.186:6000
Looking for asterisk in messages (domain 190.66.155.15)
<--- Transmitting (NAT) to 79.44.192.186:6000 --->
SIP/2.0 404 Not Found
Via: SIP/2.0/UDP 192.168.1.101:6000;branch=z9hG4bK-d8754z-e77ccb0a9afa464b-1---d8754z-;received=79.44.192.186;rport=6000
From: "209"<sip:209@voztovoice.noip.us:2464>;tag=2cf27935
To: "xmpp:voztovoice@voztovoice.net/Spark 2.6.3"<sip:asterisk@190.66.155.15:2464>;tag=as502bc767
Call-ID: OGVjNzAzM2FlODUzNzdiN2M5OWRiYjAyODU1M2JlOGU
CSeq: 7 MESSAGE
Server: Raspberry pi PBX
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH
Supported: replaces, timer
Content-Length: 0
Como se puede ver Asterisk intenta enviar el mensaje al contexto [messages] extensión asterisk. Si se fijan en el segundo bloque, campo To: aparece el usuario XMPP voztovoice@voztovoice.net. Utilizando estas dos informaciones se modifica nuevamente el dialplan y en el contexto [messages] se añade un segundo bloque:
exten => asterisk,1,Noop(Mensaje hacia usuarios XMPP)
same => n,NoOp(${MESSAGE(from)})
same => n,Set(from=${CUT(MESSAGE(from),:,2)})
same => n,Set(from=${CUT(from,@,1)})
same => n,Set(from=${DB(ext/${from})})
same => n,NoOp(${MESSAGE_DATA(to)})
same => n,Set(to=${MESSAGE_DATA(to)})
same => n,Set(to=${CUT(to,:,2)})
same => n,Set(to=${CUT(to,/,1)})
same => n,Noop(Texto = ${MESSAGE(body)})
same => n,JabberSend(${from},${to},${MESSAGE(body)})
same => n,Noop(Estado del mensaje ${MESSAGE_SEND_STATUS})
same => n,Hangup
Primero desde la variable ${MESSAGE(from)} se extrae con la función CUT el numero de la extensión que está enviando el mensaje. Luego se lee en la base de datos interna de Asterisk que usuario XMPP está asociado a la extensión que está enviando el mensaje, Con la función MESSAGE_DATA se lee el campo To: del mensaje enviado y luego utilizando la función CUT se extrae solamente el usuario XMPP. Luego se utiliza la aplicación JabberSend para enviar el mensaje al usuario XMPP voztovoice. La sintaxis de la aplicación es:
JabberSend(account,jid,message)
- account es la cuenta configurada en el archivo xmpp.conf que se utilizará para enviar el mensaje
- jid es el usuario al que se enviará el mensaje escrito junto al dominio
- message es el texto del mensaje que se enviará:
Se guardan los cambios y se recarga el dialplan:
asterisk -rvvvvvvvvvvvv
CLI> dialplan reload
Se intenta enviar nuevamente el mensaje desde X-Lite:
En el cliente Spark:
El Gateway funciona perfectamente. Ahora la primera pregunta. Si se quiere empezar la chat desde el X-Lite, ¿cómo se hace para enviar el mensaje al usuario voztovoice? Se modifica nuevamente el dialplan y en el contexto utilizado para el monitoreo de las extensiones (en mi caso [subscribe]) se añade la siguiente línea:
exten => voztovoice,hint,custom:voztovoice
es decir que se crea el monitoreo de una extensión personalizada. Se recarga el dialplan y se añade el contacto a la lista de contactos del X-Lite. El resultado:
Hay que decir que el usuario voztovoice siempre aparecerá en línea ya, que yo sepa, no hay posibilidad de monitorear extensiones XMPP con la prioridad hint. Se podría utilizar la función JABBER_STATUS para saber, antes de enviar el mensaje, si el usuario XMPP se encuentra en línea o no. El problema es que parece que esa función no responde como debería. Esperemos que ese problema se corrija pronto. Mientras vamos sencillamente a enviar el mensaje. Se abre nuevamente el dialplan:
nano /etc/asterisk/extensions.conf
y en el contexto [messages] añadimos el siguiente bloque:
exten => _[a-z].,1,NoOp(mensaje SIP -> XMPP directo)
same => n,NoOp(${MESSAGE(from)})
same => n,Set(from=${CUT(MESSAGE(from),:,2)})
same => n,Set(from=${CUT(from,@,1)})
same => n,Set(from=${DB(ext/${from})})
same => n,JabberSend(${from},${EXTEN}@voztovoice.net,${MESSAGE(body)})
same => n,Hangup
Para que funcione todos los usuarios XMPP deberán tener un nombre que empiece con una letra minúscula. Se guardan los cambios y se recarga el dialplan:
asterisk -rvvvvvvvvvvvvvvvv
CLI> dialplan reload
desde el X-Lite se envía un mensaje al usuario XMPP voztovoice:
En el cliente Spark:
La configuración del “Gateway” parece un poco complicada pero la verdad es bastante sencilla.
¿Qué opinan?
1 comentario
sip:Unknown - Usuario SIP desconocido
Enviado por Márcio (no verificado) el
Hola,
Perdón por mi español (portuñol :-)
En las mensajes desde uno usuario xmpp (maria) hasta uno usuario xmpp en asterisk (juan), el usuario sip (de maria) queda desconocido.
From: "xmpp:maria@servidor.xmpp.externo/laboratorio" (sip:Unknown@servidor.sip.interno)
Entonces las mensajes desde el usuario sip (juan, extension 1020) hasta el el usuario xmpp externo (maria) generan un error 404.
?Que puedo hacer?
Gracias por el post.
Marcio
(--- XMPP received from 'juan' ---)
(message from='maria@servidor.xmpp.externo/laboratorio' to='juan@servidor.xmpp.externo' type='chat' id='purple8c2211d
d')(active xmlns='http://jabber.org/protocol/chatstates'/)(body)00000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000(/body)(/message)
(-------------)
Reliably Transmitting (NAT) to servidor.sip.interno:52764:
MESSAGE sip:1020@192.168.0.105:52764;ob SIP/2.0
Via: SIP/2.0/UDP servidor.sip.interno:5060;branch=z9hG4bK074a16d4;rport
From: "xmpp:maria@servidor.xmpp.externo/laboratorio" (sip:Unknown@servidor.sip.interno);tag=as4425790f
To: (sip:1020@192.168.0.105:52764;ob)
Contact: (sip:Unknown@servidor.sip.interno:5060)
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000