Mi Brain-Training Personal

Para que no se me olviden las cosas…

Usar SIP con Google Voice ahora que van ha cerrar Gizmo5

No es que lo use mucho, pero tengo Google Voice desde hace bastante, y este fin de semana me sorprendió la noticia de que cerraban el servicio de Gizmo5 el día 3 de abril. No tengo ni idea de lo que Google pretende con Google Voice, pero lo que está haciendo por el momento no es nada particularmente interesante para mi, y el hecho de que eliminen el soporte SIP apesta bastante. :-S

Aún así, no todo está perdido, podemos utilizar SIP con Google Voice, aunque vamos a necesitar un intermediario, en este caso Asterisk.

Como hay decenas de tutoriales por ahí, os voy a enlazar el del wiki de Asterisk, ya que lo mantienen actualizado: https://wiki.asterisk.org/wiki/display/AST/Calling+using+Google

Desde Asterisk 1.8.X Google Voice funciona sin problemas (recordemos que Google no utiliza el estándar Jingle, sino una variante) así que e una muy buena herramienta para hacernos la pasarela Google Voice <-> SIP.

Pero siempre hay algún pero:

  • Ahora dependemos de la disponibilidad de nuestro Asterisk, mientras que antes Gizmo5 se encargaba de que estuviéramos online 24×7.
  • Si registramos una cuenta SIP sin más en nuestro Asterisk no tendremos parallel forking. Esto es un BUG como una catedral para los que, como yo, tienen 14 SIP-cosas conectadas a la vez.

Una de las cosas que podemos hacer para mejorar un poco la situación es registrar una cuenta SIP de verdad desde nuestro Asterisk, de manera que el proxy responsable de nuestra cuenta se encargue del parallel forking. Podéis utilizar el servicio gratuito de SIP2SIP.info, las instrucciones para configurarlo con Asterisk las podéis encontrar aquí.

Happy dialing!

La foto la he tomado prestada de aquí.

Blink y SylkServer el viernes en la VUC

Tras el lanzamiento de SylkServer hace algunas semanas Randy, que se encarga de hacer la VoIP Users Conference posible se punso en contacto con nosotros para que algún día participaramos como invitados y hablar de SylkServer y demás.

Será este viernes 18 de febrero y durante el tiempo que nos dejen hablaremos sobre el desarollo de Blink y SylkServer, haciendo incapié en las aplicaciones que se pueden desarrollar para SylkServer. Como ya comenté en su día, suele estar entretenido, y aunque es a una hora un poco mala para los europeos, pero ¡no me falléis el viernes!

Más información aquí.

Developing rich SIP applications with SIPSIMPLE SDK

Hace escasos minutos que he terminado de dar la charla titulada igual que éste post en el FOSDEM 2011. A continuación podéis ver la presentación que he utilizado:



Además de la presentación, todo el código que he mostrado lo he colgado en mi cuenta de GitHub.

Espero que sirva de guía y ver muchas aplicaciones interantes creadas con SIPSIMPLE SDK ;-)

Analizando el cliente SIP de Android 2.3 (Gingerbread)

Cuando se publicó que Android 2.3 (Gingerbread) iba a traer un cliente SIP integrado muchos lo recibieron con alegría, yo personalmente me mostre escéptico ante el asunto y ahora que he podido probarlo paso a comentar mi experiencia.

Lo primero que nos encontramos al acceder al menú de configuración es una interfaz bastante sencilla (tampoco me esperaba encontrar opciones de ICE en la primera versión) en la que sin entrar en ningún menu avanzado se nos pide usuario, contraseña y servidor.

Aquí he encontrado el primer problema. Me he puesto a capturar el tráfico con ngrep en el servidor y al habilitar la opción de registro este es el REGISTER que se ha generado:

U +4.002042 192.168.99.36:46287 -> 81.23.228.161:5060
REGISTER sip:sip2sip.info SIP/2.0
Call-ID: a812225af963d74d1f448421baf0e935@192.168.99.36
CSeq: 3879 REGISTER
From: "saghul" <sip:saghul@sip2sip.info:5060>;tag=578921570
To: "saghul" <sip:saghul@sip2sip.info:5060>
Via: SIP/2.0/UDP 192.168.99.36:46287;branch=z9hG4bKe3516d385aa81d7768be12f905d7d1e6333939;rport
Max-Forwards: 70
User-Agent: SIPAUA/0.1.001
Contact: "saghul" <sip:saghul@192.168.99.36:46287;transport=udp>
Expires: 3600
Content-Length: 0

view raw gistfile1.txt This Gist brought to you by GitHub.

La primera línea la he dejado aposta, ya que es la información que ngrep añade acerca del origen y destino del paquete. El problema es que el REGISTER se manda a la IP obtenida como resultado de una consulta DNS de tipo A, el cliente SIP de Gingerbread no hace consultas DNS SRV. Si a día de hoy alguien saca un cliente de correo que no consulta los registros MX sería lanzado a los tiburones, pero parece que en el caso de SIP todo vale, en fín.

Aun siendo casi inusable para mí he añadido un outbound proxy para que solo hiciera la consulta de tipo A. Y así ha quedado el REGISTER:

U +0.085305 192.168.99.36:60583 -> 81.23.228.146:5060
REGISTER sip:sip2sip.info:5060;maddr=node03.dns-hosting.info SIP/2.0
Call-ID: 2886516c9522d3e8f60702067e35e954@192.168.99.36
CSeq: 3404 REGISTER
From: "saghul" <sip:saghul@sip2sip.info:5060>;tag=1294656353
To: "saghul" <sip:saghul@sip2sip.info:5060>
Via: SIP/2.0/UDP 192.168.99.36:60583;branch=z9hG4bKfbf000b5535dc024e1bdaf7953e1d070333939;rport
Max-Forwards: 70
User-Agent: SIPAUA/0.1.001
Contact: "saghul" <sip:saghul@192.168.99.36:60583;transport=udp>
Expires: 3600
Authorization: Digest username="saghul",realm="sip2sip.info",nonce="4d489674bb8d20a695c6d425a4460893028cddb4",uri="sip:sip2sip.info:5060;maddr=node03.dns-hosting.info",response="xxxxx"
Content-Length: 0

view raw gistfile1.txt This Gist brought to you by GitHub.

¿Y ese maddr? Es una forma deprecated de forzar una ruta para el mensaje en cuestión. Veamos qué dice la biblia al respecto:

The maddr field has been used as a simple form of loose source routing. It allows a URI to specify a proxy that must be traversed en-route to the destination. Continuing to use the maddr parameter this way is strongly discouraged (the mechanisms that enable it are deprecated). Implementations should instead use the Route mechanism described in this document, establishing a pre-existing route set if necessary (see Section 8.1.1.1). This provides a full URI to describe the node to be traversed.

Vamos, que ya en el 2002, cuando se publicó el 3261 maddr estaba obsoleto. Pero aun así la última versión de Android lo incluye. A tope con el SIP.

Hay más: si deseleccionamos la opción de registrarnos es de suponer que se genere un REGISTER eliminando nuestro binding, ¿no? Pues no.

Pasemos al INVITE. No he enredado mucho porque llegado este punto me encontraba demasiado cabreado, así que he hecho lo posible por hacer una llamada, pero no ha sido fácil. En la plataforma sip2sip.info al llamar al 3333@sip2sip.info se sobrescribe la parte del host para mandar el request a otro servidor, pero al tener el atributo maddr OpenSIPS se hace la picha un lío y no sabe muy bien qué hacer. -1 para OpenSIPS en esta.

En concreto se trata de un bug no resuelto que podéis consultar aquí. Para solucionarlo he reescrito el RURI eliminando todos los parámetros de la URI en caso de que se encuentre maddr:

if($(ru{uri.maddr}) != "") {
    $ru = "sip:" + $rU + "@" + $rd;
}

Es una cerdada, pero ha servido para poder hacer una llamda de prueba. Milagrosamente ha funcionado.

Conclusión

El cliente SIP de Android 2.3 no funciona. Puede funcionar en entornos muy simples, pero en nada que podamos considerar serio. Creo que no debería haber sido incluido en Android hasta estar más maduro, ya tenemos clientes SIP que funcionan en Android, como Bria, SIPDroid o CSipSimple. Para tener un cliente tan mediocre mejor no tener nada. Suena severo, pero la primera impresión es importante y en mi caso es nefasta, así que el Nexus One volverá al cajón hasta que otra noche que me aburra lo saque para ver si ha mejorado algo.

PD: La foto la he tomado prestada de El Androide Libre, me daba algo de pereza sacar el screenshot :-)

free(SylkServer);

Me alegra mucho poder escribir hoy este post. Hace algun tiempo que publicamos en Twitter que SylkServer sería lanzado pronto. Pues ese día es hoy.

SylkServer empezó como una evolución del anterior switch MSRPSIP-chatserver. El chatserver estaba desarrollado con el API de una versión muy antigua de SIPSIMPLE, por lo que era necesario reescribir gran parte de su código. La tarea resultó más sencilla de lo esperado ya que la versión actul de SIPSIMPLE proporciona una API de mucho más alto nivel que permite una interacción sencilla con sesiones SIP con distintos tipos de streams como MSRP o RTP.

Una vez teníamos el nuevo chatserver pensamos en añadir soporte para otros timos de media, así que añadimos soporte para audio. De esta manera tenemos una conferencia que se lleva a cabo en 2 planos: audio y texto. Pero no todo el mundo tiene un cliente SIP con soporte para MSRP así que añadimos también soporte para SIP MESSAGE. Al ser un servidor de conferencias, los mensajes tienen que ser enviados ‘de parte de los usuaris’, por lo que CPIM es imprescindible. Cual fue mi sorpresa al comprobar que ningún softphone que probé lo soportaba :-( . Dejo la importancia de CPIM para un futuro post.

Una vez teníamos audio y chat nos faltaba algo muy importante: la lista de participantes. Afortunadamente tenemos una manera estándar de hacerlo: el evento conference (RFC4575). Al suscribirnos al evento conference, el servidor nos enviará un NOTIFY con un XML describiendo la sala de conferencias, incluyendo la lista de participantes. Blink se suscribe automágicamente a éste evento (cuando recibe un 200 OK del servidor con el parámetro isfocus en la cabecera Contact, para ser más exactos) y nos presentará la lista de participantes de la siguiente manera:

Finalmente, dotamos al servidor de una arquitectura de plugins de manera que se puedan desarrollar distintas aplicaciones. De momento hemos implementado ‘conference’ y tenemos algunas en el tintero, stay tuned!

SylkServer es Software Libre (GPLv3), podéis instalaros un server propio o utilizar el de testing que tenemos funcionando.

Toda la información así como las instrucciones las tenéis disponibles en la web: http://sylkserver.com/

Mensajería en SIP con MSRP

Muchas veces hablamos de menajería y presencia, y nos quedamos en la parte de presencia. Supongo que para muchos mensajería es el SIP MESSAGE. Pues no.

SIP MESSAGE puede estar bien para intercambiar pequeños fragmentos de datos sin demasiado contexto, como un SMS en los móviles. Recordemos que a día de hoy lo que más se utiliza es SIP sobre UDP, por lo que sufrimos los problemas inherentes a este entorno:

  • Falta de seguridad, los mensajes viajan en claro.
  • Fragmentación. Si intentamos mandar un mensaje demasiado grande, y es fraccionado por nuestro router hay muchas posibilidades de que el otro extremo no se capaz de reconstruirlo.

Ámbos puntos anteriores pueden ser solventados utilizando SIP sobre TCP, pero aún así nos faltaría solucionar el que para mi es el problema más importante: la falta de contexto. Cada SIP MESSAGE es una transacción SIP, pero no hay ningún mecanismo que los agrupe de manera que lo que percibamos sea una conversación.

MSRP (Message Session Relay Protocol), RFC4975 viene a solucionar precisamente lo que indico arriba. MSRP define un mecanismo mediante el cual se utiliza SIP para establecer una sesión entre 2 usuarios (mediante INVITE, como una llamada) y proporcionar un canal de comunicación TCP/TLS para enviar mensajes relacionados. Relacionados, esa es la clave. La sesión MSRP dura como máximo lo que dura la sesión SIP, por lo que ya tenemos el concepto de conversación.

Para establecer el canal de comunicación TCP/TLS se utiliza el modelo offer/answer del protocolo SDP (RFC4566), un viejo conocido. Veamos como es el SDP de un INVITE que nos ofrece MSRP:

v=0
o=- 3504981162 3504981162 IN IP4 192.168.99.53
s=sipsimple 0.16.5
c=IN IP4 192.168.99.53
t=0 0
m=message 2855 TCP/TLS/MSRP *
a=path:msrps://192.168.99.53:2855/89861a3e01adca494db7;tcp
a=accept-types:message/cpim text/* application/im-iscomposing+xml
a=accept-wrapped-types:*

En el caso de MSRP, como se puede observar, la IP y el puerto de encuentran duplicadas: en las líneas c/m y en el atributo path. MSRP define que las líneas c/m han de ser ignoradas yque la información significativa sobre la conexión se encuentra en el atributo path. Analicemos un poco el atributo path:

a=path:msrps://192.168.99.53:2855/89861a3e01adca494db7;tcp

En la línea m se había definido TLS como transporte, por tanto utilizamos una dirección msrps://, si fuera TCP utilizaríamos msrp://. A continuación tenemos la dirección IP puerto desde los que se realizará la conexión hacia el otro extremo. Para finalizar tenemos el identificador de sesión, y el transporte.

Veamos como se establecería una sesión de MSRP:

Todo bien, ¿no? Pues no. Todavía tenemos un problema que solucionar: el NAT. ¿Qué pasa si Bob está detrás de NAT? Obviamente no podremos atravesar su NAT para establecer una sesión MSRP. Por suerte, el RFC4976 define una extensión al protocolo MSRP para utilizar relays en el camino y poder evitar los problemas de NAT.

El funcionamiento es sencillo: un usuario que se encuentre detrás de NAT iniciará una conexión saliente hacia un servidor que haga de relay cuando reciba un INVITE. El servidor reservará un puerto y un identificador de sesión que devolverá al usuario. Ahora el usuario utilizará estos datos al construir su respuesta, por lo que el llamante no se conectará realmente al usuario, sino al relay, y el relay al usuario. Veamos que pinta tendrá la respuesta:

v=0
o=- 3504982347 3504982348 IN IP4 192.168.99.53
s=sipsimple 0.16.5
c=IN IP4 192.168.99.53
t=0 0
m=message 54005 TCP/TLS/MSRP *
a=path:msrps://node03.dns-hosting.info:2855/PaFIw7KZEhgoC6Cc5lPunTEyOTU5OTMzNTkuMjI5OjYyLjEzMS42LjU1;tcp msrps://192.168.99.53:54005/b3bda736f12bbd94e0c9;tcp
a=accept-types:message/cpim text/* application/im-iscomposing+xml
a=accept-wrapped-types:*

Como se puede observar, el atributo path tiene 2 direcciones en este caso. La primera (de izquierda a derecha) define la conexión con el servidor relay, y la de más a la derecha la conexión del relay con el receptor. Hay 2 identificadores de sesión, el del servidor y el del cliente. Cuando el llamante inicie una conexión TCP lo hará contra el servidor, que al estar en una IP pública recibirá sin problema, y luego encaminará todos los mensajes hacia el otro usuario.

Veamos como queda ahora la secuencia para establecer una sesión MSRP:

Lo mejor de todo es que esto existe y se puede probar hoy y ahora, en el MundoReal(TM):

Creo que vale por hoy, dejamos el soporte de transferencia de ficheros a través de MSRP para otro día :-)

FOSDEM 2011, ¡allá vamos!

Como cada año, en el 2011 también se celebrará la Free and Open Source European Developers Meeting o FOSDEM del 5 al 6 de febrero en Bélgica. Ya que los Belgas son vecinos y la entrada es gratuita no tengo excusa para no ir desde Amsterdam.

Pero este año hay un track especialmente interesante para mi (y algún que otro fan de la VoIP): el Open Source Telephony Devroom. Hace dos días que Russell Bryant publicó la lista de charlas entre las cuales se encuentra una que me han aceptado: Developing rich VoIP applications with SIPSIMPLE SDK.

En la charla coemntaré la arquitectura y funcionamiento de la librería que hace posible que Blink funcione. Habrá ejemplos practicos, alguna frikada y algo de live coding. :-)

Esta es la lista de todas las charlas del Open Source Telephony Devroom:

  • “Introduction to Asterisk Developement”, Russell Bryant
  • “Digital PSTN Connectivity with Asterisk”, Jakub Klausa
  • “Mobicents 2.0, The Open Source Java Communication Platform”, Jean Deruelle
  • “Scaling location services in large SIP networks with Kamailio”, Henning Westerholt & Marius Zbihlei
  • “Unifying SIP and Web worlds with Lua (Kamailio)”, Daniel-Constantin Mierla
  • “XiVO IPBX OpenHardware”, Xavier Carcelle
  • “Unified Communications - Future (Yate and YateClient)”, Diana Cionoiu
  • “Asterisk SCF (Scalable Communications Framework)”, Kevin P. Fleming
  • “Developing rich VoIP applications with SIPSIMPLE SDK”, Saúl Ibarra Corretgé
  • “SIP Communicator: Building a Multi-Protocol Multi-OS Communications Client”, Emil Ivov

Además de las charas el viernes es el Beer Event, también habrá PGP signing party, … ¿alguno se anima?

Publicado sip:provider CE

Ante todo, y para despistados, aclarar que no soy saghul. Soy Jon Bonilla (aka manwe)  y escribo en este blog por cortesía de mi buen amigo saghul.

Sipwise acaba de publicar la primera versión de su sip:provider CE. Una plataforma completamente libre, que permite a operadores e ITSPs ofrecer servicios de telefonía en unos pocos minutos y sin complejas instalaciones o integraciones. Podéis ver el anuncio en la web de Sipwise.

sip:provider CE es una nueva versión de los productos de Sipwise basados en la tecnología NGCP y que desde hace años son usados por algunos de los mayores operadores de Europa. Esta versión, compuesta exclusivamente por aplicaciones libres, se ha centrado en ofrecer una solución completa y una interfaz lo suficientemente sencilla como para que cualquiera pueda instalar y ofrecer servicios de telefonía sin tener exhaustivos conocimientos de SIP, Kamailio, Asterisk, Sems, Billing, Rating… etc. Las interfaces de usuario están disponibles en español además de inglés.

Desde aquí os animo a probar este nuevo producto. La instalación, completamente desatendida, lleva menos de 10 minutos con una buena conexión a internet. Y la configuración básica de la solución lleva otros 10. Eso quiere decir que ¡podéis poner un sistema profesional  de VoIP en servicio en menos de 20 minutos!

PD: Por si no se ha notado en el sesgo del artículo, trabajo en Sipwise y durante el último año he liderado el equipo de desarrollo de los productos sip:provider CE y sip:provider PRO.

Sobre Android Gingerbread y su API SIP

Hoy dandome una vuelta por mis RSS me he encontrado los los posts en SinoLogic y VoIP Novatos comentando que la nueva versión de Android, 2.3 o Gingerbread, incluye una API para desarrollar aplicaciones VoIP basadas en SIP.

La verdad es que me he quedado bastante sorprendido, así que lo primero que he hecho ha sido echar un vistazo a la documentación. Pero como dijo el Señor Lobo:

Tras un paseo rápido por el API me he quedado bastante decepcionado. Parece muy básica y solo permite implementar llamadas de audio. Nada de mensajería. Nada de presencia.

Además, mirando la documentación de SipSession, nos encontramos con esta perla:

Defines SIP session states, such as “registering”, “outgoing call”, and “in call”.

¿Cómo? ¿Desde cuando usa sesión puede estar “registering”? Vale que quieran que el API sea sencillo, pero el registro y una sesión SIP no están para nada relacionados.

Supongo que le irán añadiendo features, y tal vez en Android 3.0 mejore… De momento me quedo con Bria (tuve la suerte de ser betatester) y cSipSimple en Android.

Veremos que nos depara el futuro ;-)

click2dial en tu web en 5 minutos con Phono SDK

Un tema que suele aparecer de cuando en cuando en la lista de Asterisk-ES es cómo poner un sistema de click2dial en una web de manera que el navegante no se gaste un centimo en llamarnos. Hoy vamos a ver cómo hacerlo en 5 minutos con Phono SDK.

Phono SDK es un plugin de jQuery mediante el cual podemos hacer (¡y recibir¡) llamadas y mensajes. Ha sido desarrollado por los chicos de Voxeo Labs y yo al menos no conozco una manera mas sencilla para hacer una llamada de telefono desde el navegador. Con Phono puedes hacer llamadas desde la web de manera gratuita a cualquier URI SIP e incluso podemos conectarlo a aplicaciones de Tropo (de esto hablaremos en otro post largo y tendido).

Como aquí nos gusta saber cómo funcionan las cosas, veamos la arquitectura del asunto:

La comunicación entre el navegador y el servidor de Phono se realiza con los protocolos XMPP y Jingle encapsulados en RTMP. Si, Phono utiliza flash (de momento) para poder acceder al microfono y altavoces del usuario. Me consta que están trabajando en una version 100% HTML5 para mandar Flash a /dev/null, esperemos que sea pronto :)

En los servidores de Phono se realiza la conversion de XMPP y Jingle a SIP y RTP y se envia la llamada al destino correspondiente.

Podéis probar la demo que he hecho en 5 minutos aquí, o descargar el código en este Gist. Al hacer click en call llamaréis a sip:3333@sip2sip.info, un servicio de prueba en el que se escucha la sintonía de James Bond. También podéis instalar este plugin para WordPress y que la peña os deje comentarios de voz en el blog o algo… :-)

La prueba es muy sencilla (aunque he tenido que recordar lo que Jabi me enseñó de jQuery, que entre tanta llave y paréntesis me pierdo :) ) pero ilustra lo sencillo que nos puede resultar añadir esta funcionalidad a una web corporativa, sin utilizar ActiveX ni webphones en Java ni nada parecido, aunque Flash no me guste demasiado ;-)

Happy Phono-ing!