Sip Proxy - Pag34
Sip Proxy - Pag34
Sip Proxy - Pag34
“Unidad Zacatenco”
TESIS
Presentan:
Liliana Aguilar Hernández
Agustín Moreno Nájera
Asesores:
M. en C. Genaro Zavala Mejía
M. en C. Fernando Noya Chávez
Diciembre 2011
1
Índice General
Índice de figuras………………………….……………………….………………. 4
Índice de tablas…………………………………………………………..………... 6
Introducción……………………………………………………………………….. 7
Descripción…………………………………........................................................... 9
Justificación…………………………………………………………….................. 10
Objetivos………………………………………………………………………….. 10
Diagrama a bloques……………………………………………………………….. 11
1.2 VoIP…………………………………………………………………… 15
1.2.1 Antecedentes de telefonía convencional…………………… 15
1.2.2 Estado actual de la Telefonía IP bajo la tecnología VoIP….. 17
2.3 VoIP…………………………………………………………………..... 26
2.3.1 Introducción a la VoIP …………………………………….. 26
2.3.2 Definición………………………………………………..... 26
2.3.3 Implementación y funcionamiento…………………………. 27
2.3.4 Control de la comunicación…………………………………. 27
2.3.5 Parámetros VoIP……………………………………………. 28
1.2.5.1 Códec……………………………………………….. 28
1.2.5.2 Protocolos de señalización …………………………. 28
1.2.5.3 Protocolos de transporte de voz
y ancho de banda de la voz ………………………………… 29
2.3.6 Ventajas…………………………………………………….. 29
Capítulo IV Desarrollo………………………………………………………. 59
Capítulo V Pruebas………………………………………………………… 76
5.1 Registro de teléfono SIP…………………………………………. 76
5.1.1 Resultados……………………………………………....... 77
Conclusiones…………………………………………………………. 84
Glosario…..………………………………………………………....... 85
Anexos .………………………………………………………………. 86
Bibliografía…………………………………………………………… 122
3
Índice de figuras
4
Figura 23. Proceso de autenticación y registro de un UAC……………………… 66
5
Índice de tablas
6
Introducción
La telefonía de hoy en día, tal y como la hemos conocido siempre, está llegando a
su fin. La era de las nuevas tecnologías, con Internet a la cabeza, le están ganando terreno a
grandes consorcios tecnológicos que han permanecido invariables e intocables durante
mucho tiempo. El mundo de las comunicaciones por voz es uno de ellos.
7
La telefonía IP comenzó a principios de las décadas de los 90 1, aunque la mala
calidad de la voz y el impulso que en aquellos momentos estaba tomando la RDSI (Red
digital de servicios integrados) hicieron que no pasara de ser solo un experimento. Durante
esta década se produjo el auge de Internet, lo que hizo que todos los esfuerzos, tanto de las
empresas como de los operadores fueran dirigidos a potenciar su uso y las aplicaciones de
navegación Web y correo electrónico, fueron las que más éxito tuvieron, lo que junto al
despliegue de las redes móviles dejaron la voz relegada en un tercer plano.
1
José Manuel Huidobro Moya, Tecnología IP y Telefonía VoIP, 2006.
8
Descripción
Para lograr la comunicación entre el servidor y sus clientes, será necesario hacer uso
de diversos protocolos, mediante el modelo OSI. En la capa 1 (Física) se utilizará como
medio de transmisión cable UTP categoría 5 utilizado normalmente en redes LAN. En la
capa 2 (Enlace de datos) se requerirá un switch para concentrar todas las terminales
existentes conectadas al servidor. Siguiendo con la capa 3 (Red) se implementará el
protocolo IP y con esto se configurarán los clientes dentro de un dominio para ser visibles
por el servidor. Dentro de la capa 4 (Transporte) para que exista transmisión de datos se
hará uso del protocolo UDP basado en el envío de datagramas, el cual resulta de mayor
factibilidad para transmitir voz en tiempo real. Por último en la capa de aplicación el
protocolo SIP tomará un papel importante para lograr la comunicación y reconocimiento de
las aplicaciones entre cliente y servidor.
9
Justificación
Objetivos
Objetivo General:
Objetivos Particulares:
10
Diagrama a bloques del proyecto y sus alcances
IP
SIP
Servidor de
Registro
UPD/RTP
PROXY PBX
UAC 1 VoIP PSTN
Reporteador Gateway
.
.
UAC 2
.
.
.
.
UAC
.
11
CAPITULO I. ESTADO DEL ARTE
1.1 PBX
1.1.1 Antecedentes
El primero era que las operadoras podían escuchar las llamadas y la segunda causa fue el
error humano, ya que en ocasiones se enlazaban las llamadas a lugares equivocados. La
solución, realizar este procedimiento mediante maquinas automáticas.
2
Private Manual Branch Exchange
12
A partir de este punto, el avance de la telefonía, estuvo íntimamente ligado al
desarrollo de los sistemas de cómputo ya que, aunque los equipos que reemplazaban a los
PMBX todavía utilizaban tecnología convencional, su sistema central ya estaba basado en
una computadora. Gracias a este avance, se comenzaron a agregar funciones útiles tanto en
telefonía pública como en la telefonía corporativa y así, se obtenían cada vez más
beneficios, más funcionalidad, mayor capacidad y menor costo.
PBX
Servicio de PBX Virtual
IP PBX
Servicio de IP PBX Virtual
Una la de las aplicaciones más conocidas para realizar este tipo de funciones es la
llamada Asterisk que fue creada en el año de 1999 por Mark Spencer de la empresa Digium
y donada a la comunidad con licencia libre tras lo cual se han recibido muchas
colaboraciones y mejoras por parte de muchos desarrolladores libres y empresas sin
solicitar nada a cambio.
13
Poco a poco, esta aplicación se ha convertido en la evolución de las tradicionales
centralitas analógicas y digitales permitiendo también la integración de la tecnología más
actual: VoIP. Asterisk ha sido un sistema de comunicaciones completo, avanzado y
económico en la actualidad.
Este sistema permite realizar labores que hasta el día de hoy lo llevaban realizando
sistemas extremadamente costosos y complicados.
Una de las ventajas más interesantes es su posibilidad como sistema híbrido, ya que
permite gestionar comunicaciones telefónicas tradicionales (analógicas, digitales, móviles,
etc.) como comunicaciones IP mediante el uso de los protocolos estándar de VoIP. A pesar
de las ventajas que nos ofrece Asterisk, presenta deficiencias en plataformas para Windows,
ya que carece de funcionalidades para generar reportes de llamadas. Dicha función, al ser
una pieza fundamental para un sistema PBX, el cliente se ve en la necesidad de adquirir
este complemento, lo cual incrementa costos debido al desarrollo y soporte técnico en el
extranjero.
14
1.2 VoIP
En la primera etapa (1878), cada terminal debía realizar la unión con los teléfonos
remotos mediante un cable, donde si no existía conexión en los dos extremos, era imposible
efectuar la comunicación. Eso provocó la aparición de múltiples cables tirados por las
ciudades uniendo teléfonos particulares.
En la segunda etapa (1891), una entidad global se encargó de gestionar los cables,
de modo que cada teléfono se unió a una central (ver figura 3). Cuando alguien deseaba
realizar una llamada, en la central se unían los cables de ambos teléfonos, lo que permitía
hablar con cualquier teléfono que estuviera conectado a la central, sin necesidad de
conectar un cable específico con cada teléfono. Para conseguir esto, se hizo necesaria la
identificación de cada teléfono mediante un número.
15
Figura 3: Telefonía conectada a central
Con el paso de los años, las nuevas tecnologías han adquirido un papel muy
importante dentro de las comunicaciones, como lo es la tecnología VoIP que da lugar a la
implementación de la telefonía IP que se viene abriendo paso frente a la telefonía
convencional.
Durante los años siguientes, la tecnología asociada a las redes de datos y las
comunicaciones continuó mejorando, para ser en 1998 cuando se dieron definitivamente los
primeros pasos desde un punto de vista comercial. En este año diversas compañías lanzaron
al mercado adaptadores que permitían hacer uso de los teléfonos tradicionales en un
entorno VoIP. Ello facilitó el acercamiento a los clientes a la hora de poder hacer uso de la
17
tecnología VoIP, por lo que algunas empresas importantes se lanzaron al mercado
ofreciendo productos y servicios relacionados con esta tecnología. Durante el año 1998 la
tecnología VoIP alcanzaba ya el 1% del tráfico total de voz: su carrera había comenzado.
En 19993, compañías dedicadas a las redes de datos tales como CISCO crearon las
primeras plataformas destinadas a empresas capaces de tratar con tráfico VoIP. Esto supuso
un nuevo impulso a la VoIP ya que comenzó a implantarse en muchas empresas. La
consecuencia directa fue que la VoIP alcanzara en el año 2000 más del 3% del tráfico total
de voz.
Las redes de datos siguieron mejorando en años venideros, y alrededor del año 2005
ya era fácil para cualquier persona de países desarrollados conseguir una conexión a
Internet que cumpliera los requisitos mínimos para ofrecer una buena calidad de voz y una
comunicación fiable a través de VoIP, reduciendo al mínimo las posibles interrupciones
que se pudieran producir durante la conversación.
Esto supuso otro gran impulso a la VoIP y provocó que al día de hoy existan
muchas soluciones que hacen uso de esta tecnología. Un ejemplo claro es Asterisk, una
centralita telefónica de software libre que se distribuye bajo licencia GPL. Este producto,
soportado comercialmente por Digium, se ha convertido en pocos años en una de las
soluciones IP más extendidas en diversos ámbitos, como el empresarial o el educativo. Otro
ejemplo destacable de producto VoIP es Skype, que fue creado por dos jóvenes
universitarios en el año 2003. A diferencia de Asterisk, Skype hace uso de un protocolo
privado que no está basado en un estándar, lo que a largo plazo se piensa que limitará a sus
usuarios. Al día de hoy Skype se puede emplear en multitud de plataformas y su uso se
encuentra también ampliamente extendido.
De un modo u otro, a finales del año 2008 se esperaba que el negocio relacionado
con la VoIP llegara a la impresionante cifra de 5000 millones de dólares. El bajo costo de
las llamadas a distancia y las nuevas funcionalidades que se están implementando son sólo
dos de los alicientes que están provocando esta revolución.
Aunque VoIP puede definirse abreviada como una tecnología que aprovecha el
protocolo TCP/IP para ofrecer conversaciones de voz, lo cierto es que es mucho más que
esto. VoIP puede ser usada para reemplazar la telefonía tradicional en un entorno
empresarial, en un pequeño negocio o en una casa, o simplemente para añadir ventajas a un
sistema de telefonía tradicional.
3
José Manuel Huidobro Moya, Tecnología IP y Telefonía VoIP, 2006
18
El proceso de convergencia ha seguido un camino pausado. No es sencillo invertir
en nuevos equipos o infraestructura como lo demanda el actual ritmo de crecimiento en
materia de TICs, por tanto se tiende a seguir un modelo híbrido donde conviven PBX
tradicionales y PBX habilitados con soporte para redes IP. Hoy en día la industria de las
telecomunicaciones ha decidido apostar fuerte por una plataforma común sobre el
Protocolo de Internet aunque, como hemos mencionado anteriormente, ha decidido hacerlo
con visión de largo plazo. Para muchas organizaciones, incluyendo instituciones de
educación, la convergencia significa la oportunidad de fusionar las aplicaciones existentes
con nuevas herramientas de comunicación y nuevos modelos de transmisión de la
información cuyas posibilidades son infinitas.
En este rubro, México ocupa uno de los primeros lugares a nivel América Latina en
el uso de la telefonía IP. Cada vez, más organizaciones están optando por los beneficios de
la convergencia al mundo IP. El mercado de la telefonía por Internet ha crecido
constantemente en los últimos años y seguirá con esta tendencia en el futuro próximo.
19
CAPÍTULO II. MARCO TEÓRICO
2.1 PBX
2.1.1 Definición
Private. Debido a que este tipo de sistemas e instalaciones tienen un uso privado
cuyos servicios no se encuentran disponibles desde otras redes de telefonía de
acceso público.
Automatic. Se refiere al modo de conmutación que desde hace ya mucho tiempo
es automático para todos los equipos por lo que normalmente en vez de decir
PABX se dice PBX.
Branch. Sugiere que los equipos conectados a estas redes privadas se comportan
en realidad como una ramificación de las grandes redes de acceso público.
Exchange. Debido a que estos sistemas permiten intercambiar información, es su
caso esta información son sobre todo llamadas telefónicas.
2.1.2 IP PBX
Para disponer de las funciones de una centralita telefónica IP PBX se tienen varias
opciones: IP PBX basada en hardware, IP PBX basada en software, IP Centrex y PBX
híbrida con soporte VoIP.
20
2.1.2.1 Características
Una centralita telefónica IP PBX permite comunicación de voz y/o video a través de
las redes de datos, utilizando tecnología VoIP así como interactuar con las líneas
telefónicas convencionales PSTN o RTC (Red Telefónica Conmutada), tanto analógicas
RTB (Red Telefónica Básica) como digitales RDSI (Red Digital de Servicios Integrados) y
móviles GSM/GPRS/UMTS.
Una centralita telefónica IP PBX trabaja internamente con el protocolo IP, utilizando
infraestructuras de comunicaciones de datos basadas en IP, como Internet, LAN (Local
Area Network, Red de área local), WLAN (Wireless LAN, Wireless Local Area Network,
Red de área local inalámbrica) y WAN (Wide Area Network, Red de área amplia).
PBX con soporte VoIP (también llamada PBX híbrida): la mayoría de PBX
tradicionales pueden disponer de las funciones de una centralita IP PBX conectando
módulos donde se incorpora la tecnología VoIP.
Los teléfonos IP, así como los teléfonos IP DECT, se conectan en la LAN y se registran en
la centralita telefónica IP PBX.
21
Las PC’s de la red, tanto con conexión cableada como Wi-Fi, pueden acceder a la centralita
telefónica IP PBX a través de la LAN, realizando llamadas mediante Softphones
registrados en el IP PBX.
Un gateway VoIP o ATA (Analog Telephone Adapter), permite conectar con equipos
estándar, como teléfonos analógicos, faxes o teléfonos inalámbricos DECT.
La telefonía VoIP permite extender la red telefónica privada a través de Internet, integrando
de ese modo oficinas remotas en la infraestructura de comunicaciones de la empresa. Los
usuarios acceden a los servicios que proporciona la centralita PBX IP a través de diversos
dispositivos, entre los cuales se encuentran los teléfonos IP, Softphones, Fax, mensajería
instantánea, sistemas de videoconferencia, dispositivos móviles, etc.
Para el usuario, hablar con el servidor proxy es como hablar directamente con el verdadero
servidor. En cuanto a éste último, habla con un usuario en el anfitrión que ejecuta el
servidor proxy; no sabe que el usuario en realidad está en otro lugar.
22
2.2.2 Funcionamiento
Los detalles de cómo funciona un proxy varían de un servicio a otro. Algunos servicios
proporcionan un proxy fácil o automáticamente; para esos servicios, un proxy se instala al
realizar cambios de configuración a los servidores normales. Sin embargo, para la mayoría
de los servicios la instalación de un proxy requiere de un software apropiado para servidor
proxy del lado del servidor. De lado del cliente, necesita uno de los siguientes:
Con este enfoque, el software debe saber cómo ponerse en contacto con el servidor proxy
en lugar de con el verdadero servidor cuando un usuario hace una solicitud, y cómo decirle
al servidor proxy con cual servidor real conectarse.
Con este enfoque, el usuario utiliza el software cliente estándar para hablar con el servidor
proxy y le dice que se conecte con el verdadero servidor, en lugar de conectarse con el
verdadero servidor directamente.
Ventajas
Debido a que los servidores Proxy comprenden el protocolo de niveles inferiores, permiten
que se lleve la contabilidad del sistema de una forma muy efectiva.
Desventajas
Los servicios Proxy podrían requerir servidores diferentes para cada servicio
Quizá necesite un servidor Proxy para cada protocolo, por que el servidor Proxy
debe comprender el protocolo para determinar que permite y que no, y para hacerse pasar
como cliente ante el verdadero servidor y como el verdadero servidor ante el cliente proxy.
Coleccionar, instalar y configurar todos estos servidores puede requerir mucho trabajo.
23
2.2.4 Proxy a nivel de aplicación: Protocolo SIP
Tal y como trabajan los routers con los datos en general, recibiendo y enviando
peticiones desde y hacia otras maquinas, los diferentes protocolos IP necesitan igualmente
que alguien o algo encamine sus peticiones hacia los usuarios finales, a fin de establecer
una conversación. Esta tarea la realiza un servidor proxy o enrutador, encargándose de rutar
la señalización hacia los sitios adecuados en función de las indicaciones pertinentes que
cada protocolo implementa.
En este contexto, un Proxy SIP, es una entidad intermediaria que actúa como un
servidor y un cliente con el propósito de hacer peticiones en nombre de otros clientes. Un
servidor proxy principalmente juega el papel de enrutamiento, lo que significa que su
trabajo es asegurarse de que una solicitud se envía a otra entidad "más cercana" a los
dirigidos del usuario. Los proxys son también útiles para la aplicación de la política (por
ejemplo, asegurarse de que un usuario se le permite hacer una llamada). Un Proxy
interpreta, y si es necesario, reescribe partes específicas de un mensaje de solicitud antes de
enviarlo.
Stateful Proxy: Es una entidad lógica que mantiene el estado de las transacciones
durante el procesamiento de las peticiones. Permite división de una petición en
varias, con la finalidad de la localización en paralelo de la llamada y obtener la
mejor respuesta para enviarla al usuario que realizó la llamada.
Stateless Proxy: Una entidad lógica que no mantiene el estado de las transacciones
durante el procesamiento de las peticiones, únicamente reenvían mensajes.
24
Los Proxy’s SIP, son elementos que enrutan peticiones SIP al agente de usuario
servidores y las respuestas SIP a los agentes de usuario clientes. La solicitud puede
atravesar varios Proxy´s en su camino a un UAS. Cada uno hará en el enrutamiento, la
modificación de la solicitud antes de enviarlo a la siguiente elemento. Las respuestas
recorrerá el mismo conjunto de Proxy´s que la solicitud atravesó, en el orden inverso.
Al ser un proxy es una función lógica para un elemento de SIP. Cuando una solicitud
de llega, un elemento que puede desempeñar el papel de un primer indicador decide si es
necesario responder a la solicitud por su propia cuenta. Por ejemplo, la solicitud puede ser
incorrecta o el elemento puede necesitar credenciales del cliente antes de actuar como un
proxy. El elemento puede responder con cualquier código de error apropiado. Al responder
directamente a una solicitud, la elemento es el papel de un UAS.
25
2.3 TECNOLOGÍA VoIP
Sin embargo y mientras que los datos no son sensibles al retardo, a la alteración del
orden en que llegan los paquetes, o la pérdida de alguno de ellos, ya que en el extremo
lejano se reconstruyen, la voz y la imagen necesitan transmitirse en tiempo real, siendo
especialmente sensibles a cualquier alteración que se pueda dar en sus características.
Requieren por tanto de redes que ofrezcan un alto grado de servicio y garanticen el ancho
de banda necesario
2.3.2 Definición
Al igual que ocurre en cualquier red, las redes de voz sobre paquetes requieren de
una serie de normas que especifican las funcionalidades y servicios que este tipo de redes
deben proveer en todas y cada una de sus dimensiones. Estas normas son los protocolos, y
un aspecto muy importante es que tengan carácter abierto y que sean internacionalmente
aceptados con el fin de garantizar la interoperabilidad entre productos de distintos
fabricantes, facilitando la elección de los usuarios y disminuyendo los precios de los
equipos al fabricarse estos en mayor escala.
Uno de los principales problemas a los que se enfrentan tanto VoIP como todas las
aplicaciones que se integran al protocolo IP, es el garantizar la calidad de servicio sobre
Internet, ya que puede tener limitaciones de ancho de banda en la ruta y por lo tanto no
existe un aprovechamiento óptimo de los recursos que nos provee la red mundial de la
Internet.
2.3.5.1 Códec
La voz ha de codificarse para poder ser transmitida por la red IP. Para ello se hace
uso de códecs que garanticen la codificación y compresión del audio o del video para su
posterior decodificación y descompresión antes de poder generar un sonido o imagen
utilizable. Según el Códec utilizado en la transmisión, se utilizará más o menos ancho de
banda. La cantidad de ancho de banda utilizada suele ser directamente proporcional a la
calidad de los datos transmitidos.
Entre los códecs utilizados en VoIP encontramos los G.711, G.723.1 y el G.729
(especificados por la ITU-T). Estos Códecs tienen este tamaño en su señalización:
G.711: bit-rate de 56 o 64 Kbps.
G.722: bit-rate de 48, 56 o 64 Kbps.
G.723: bit-rate de 5,3 o 6,4 Kbps.
G.728: bit-rate de 16 Kbps.
G.729: bit-rate de 8 o 13 Kbps.
28
2.3.5.3 Protocolos de transporte de voz y ancho de banda de la voz
Son las normas que definen como debe realizarse la comunicación entre los extremos por
un canal de comunicaciones previamente establecido. Los protocolos de transporte más
empleados son RTCP, RTP, UDP y TCP.
Una vez que la llamada ha sido establecida, la voz será digitalizada y entonces
transmitida a través de la red en tramas IP. Las muestras de voz son primero encapsuladas
en RTP (Protocolo de Transporte en tiempo Real) y luego en UDP o TCP antes de ser
transmitidas en una trama IP. La siguiente figura muestra un ejemplo de una trama VoIP
sobre una red LAN y WAN.
29
2.3.6 Ventajas
VoIP tiene también algunas desventajas, sin embargo, las ventajas que puede
aportar superan claramente a éstas. A continuación se mencionan algunos de los beneficios
asociados al uso de VoIP y se ve cómo podría mejorar la comunicación por voz:
Ahorrar Dinero. En una línea RTC, tiempo significa dinero. VoIP emplea Internet
como medio de transporte, donde el único costo que se tiene es la factura mensual
de Internet a tu proveedor de servicio o ISP. Hoy en día el servicio de Internet más
común es una ADSL que se puede emplear de forma ilimitada y conlleva a un costo
fijo al mes. De esta forma, si el ADSL tiene una velocidad razonable, podrá hablar a
través de VoIP con una buena calidad de llamada y el coste seguirá siendo siempre
el mismo.
Más que voz. A estar basada en una red de paquetes, VoIP puede manejar también
otros tipos de datos además de la voz: podríamos transmitir imágenes, video o texto
30
a la vez que la voz. De esta forma, se puede hablar con alguien a la vez que se le
envían archivos o incluso a la vez que se le observa a través de una webcam.
Uso más eficiente de ancho de banda. Se sabe que el 50% de una conversación de
voz es silencio. VoIP rellena estos espacios de silencio con datos de forma que el
ancho de banda de los canales de comunicación no sean desaprovechados. La
compresión y la posibilidad de eliminar la redundancia cuando se transmite voz
serán también factores que elevarán la eficiencia de uso del ancho de banda de la
conexión.
Esquema de red flexible. La red que encontramos bajo VoIP no necesita tener un
esquema o topología en concreto. Esto hace posible que una organización pueda
hacer uso de la potencia de las tecnologías que elijan, como ATM, SONET o
Ethernet.
Cuando empleamos VoIP, la complejidad de la red inherente en las conexiones
RTC es eliminada, creándose una infraestructura flexible que puede soportar
muchos tipos de comunicación. El sistema estará más estandarizado, requerirá
menos equipamiento y su tolerancia a fallos será mayor.
Fax sobre IP. Los problemas de los servicios de fax sobre RTC son el alto costo que
conllevan para largas distancias, la atenuación de la calidad en las señales
analógicas y la incompatibilidad entre algunas máquinas cuando se comunican. La
transmisión por fax en tiempo real sobre VoIP simplemente utiliza una interfaz de
fax para convertir los datos en paquetes y asegura que éstos serán entregados
completamente y de forma segura.
Otra ventaja de este sistema es que ni siquiera se necesitará una maquina fax para
enviar y recibir fax.
31
2.4 Protocolo de aplicación SIP
2.4.1 Definición
SIP se definió en el RFC 2543 en marzo de 1999 por el grupo de trabajo MMSC
perteneciente a la IEFT. En junio del 2002, el IETF publicó una nueva revisión del SIP con
el RFC 3261.
32
´
sip:usuario@dominio[:port]
sip:usuario@direcciónIP[:port]
El dominio representa el nombre del proxy SIP que conoce la dirección IP del
terminal identificado por el usuario de dicho dominio. El puerto por defecto para SIP es
5060, aunque es posible especificar otros adicionales si es necesario.
Los agentes de usuario (User agent), o de manera abreviada UA, manejan la señalización
SIP. Se pueden dividir en dos categorías:
33
User agent client (UAC). Es un elemento que realiza peticiones SIP y acepta
respuestas SIP provenientes de UAS. Un ejemplo de UAC es un teléfono VoIP ya
que realiza peticiones SIP.
User agent server (UAS). Es el elemento encargado de aceptar las peticiones SIP
realizadas por el UAC y enviar a este la respuesta conveniente. Un teléfono VoIP
también es un ejemplo de UAS, ya que acepta peticiones de inicio de comunicación
enviadas por otro teléfono UAC.
Los intermediarios necesarios para que la comunicación entre dos UA sea posible:
Servidor Proxy
Servidor registro - localización
[email protected] 192.168.1.200
[email protected] 192.169.1.201
Una vez que los teléfonos se han registrado dentro de servidor, estos pueden
entonces realizar y recibir llamadas entre sí ya que el proxy SIP conoce sus direcciones IP
físicas/reales (mediante consultas). Habitualmente, el proxy SIP y el servidor de “registro-
localización” se encuentran juntos en el mismo software por lo general. Con esto, la
llamada será realizada con éxito.
35
informa al UAC que realizó la petición SIP para que sea este mismo el que la envíe
hacia el UA destino. Un servidor de redirección actúa realmente como un UAS.
Back – to – back user agent (B2BUA). Es una entidad intermediaria que procesa
peticiones SIP entrantes comportándose como un UAS, y responde a estas actuando
como un UAC regenerando por completo la petición SIP entrante en una nueva
petición SIP que va a ser enviada.
Los mensajes de petición son enviados por las entidades cliente a las entidades servidor.
Generalmente toda petición tiene asociada una respuesta del servidor, excepto el ACK que
no requiere respuesta. Toda respuesta SIP tiene asociado un código numérico que indica el
resultado del intento de servir la aplicación del cliente.
Cabecera SIP
Las cabeceras que aparecen en los mensajes SIP dependen del tipo de mensaje y de los
parámetros necesarios en cada uno de ellos. Se indican a continuación los campos mas
frecuentes con su significado:
37
Content –Type: Indica el tipo de flujo de información transportada en el cuerpo del
mensaje.
CSeq: Identifica unívocamente transacciones dentro de un dialogo.
Event: Indica subscripción o notificación a un evento.
From: Indica el origen de la solicitud.
Max-Forwards: Limita el número de saltos en un método
Reason: Indica la razón de finalización de la sesión.
Refer-To: Contiene el URI o URL referenciado.
Referred-By: Contiene información sobre el emisor de un mensaje de tipo REFER.
Reject-Contact: Indica el URI al que el proxy no puede hacer llegar la petición.
Require: Contiene la enumeración de características que debe soportar un servidor.
Subject: Indica el asunto de la sesión multimedia.
To: Inndica el receptor de la petición.
Via: Se utiliza para grabar la ruta seguida por la petición para utilizarla en la
respuesta.
38
2.5 Protocolo RTP
2.5.1 Definición
RTP (Real- Time Transport Protocol) es el estándar que define las comunicaciones
de audio y video en tiempo real sobre redes IP, asumiendo, por tanto, la existencia de
pérdidas y retardos y la posibilidad de variación dinámica de las características de la red en
el transcurso de la comunicación. Suministra funciones de transporte extremo a extremo y
ofrece servicios tales como identificación del tipo de carga, numeración de secuencia,
timestamping, etc. No garantiza la entrega de tráfico en tiempo real pero sí suministra los
recursos para que éste se entregue de manera sincronizada. Como su nombre indica, está
orientado a la transmisión de información en tiempo real, como la voz o video.
Las aplicaciones interactivas en tiempo real, incluidas la telefonía IP y la videoconferencia,
prometen controlar gran parte del crecimiento futuro de Internet. Por tanto, organismos de
estandarización como IETF e ITU han estado ocupados durante muchos años en el
establecimiento de estándares para esta clase de aplicaciones. Disponiendo de los
estándares apropiados para las aplicaciones interactivas en tiempo real, empresas
independientes podrán crear nuevos y convincentes productos que interoperen entre sí.
2.5.2 Funcionamiento
Normalmente, RTP se ejecuta sobre UDP. El lado del emisor encapsula un fragmento
multimedia dentro de un paquete RTP, luego encapsula ese paquete en un segmento UDP y
después pasa el segmento a IP. El lado del receptor extrae el paquete RTP del segmento
UDP, a continuación extrae el fragmento multimedia del paquete RTP y lo pasa al
reproductor multimedia para su decodificación y procesamiento.
39
2.5.3 Encapsulamiento
Cada paquete RTP incluye una cabecera fija y puede incluir también campos de cabecera
adicionales, específicos de la aplicación. La figura ilustra la cabecera fija. Los primeros
doce octetos están siempre presentes y se componen de los siguientes campos:
Relleno (1 bit): indica si los octetos de relleno aparecen al final de la carga útil. Si
es así, el último octeto de la carga útil incluye una cuenta del número de octetos de
relleno. El relleno se utiliza si la aplicación requiere que la carga útil sea un número
entero, múltiplo de alguna longitud, por ejemplo 32 bits.
Extensión (1 bit): si se establece, la cabecera fija viene seguida por exactamente una
cabecera de extensión, la cual se emplea para ampliaciones experimentales de RTP.
0 4 8 9 16 31
V P X CC M Tipo de carga Número de secuencia
útil
Marca de Tiempo
Indicador de fuente de sincronización (SSRC)
Identificador de fuente de contribución (CSRC)
.
.
.
Identificador de fuente de contribución (CSRC)
V = Versión
P = Relleno
X = Extensión
CC = Cuenta CSRC
M = Marcador
40
Marcador (1 bit): la interpretación del bit marcador depende del tipo de carga útil,
normalmente se utiliza para indicar un punto señalado en el flujo de datos.
Tipo de carga útil (7 bits): identifica el formato de la carga útil RTP, que va a
continuación de la cabecera.
Número de secuencia (16 bits): permite la detección de pérdidas y la secuenciación
de paquetes en una serie de paquetes que tengan la mima marca de tiempo.
Marca de tiempo (32 bits): corresponde al instante de generación del primer octeto
de datos de la carga útil. Las unidades de tiempo de este campo dependen del tipo
de carga útil. Los valores han de ser generados desde un reloj local situado en la
fuente.
Identificador de fuente de sincronización: un valor generado aleatoriamente que
indica de manera exclusiva cual es la fuente dentro de una sesión.
Identificador de fuente de contribución: identifica una fuente que contribuye con o
añade datos a la carga útil. Este tipo de identificadores son suministrados por un
mezclador.
41
Capítulo III Herramientas
3.1 Sockets
3.1.1 Sockets en C#
42
3.1.2 Métodos clase socket
Bind ( )
Para asociar una dirección y un puerto a un servidor, de tal manera que los
clientes sepan en donde encontrar este servicio.
Listen ( )
Accept ( )
Connect ( )
Cada uno de estos procesos (Un proceso cliente y un proceso servidor) se encuentra
en un extremo de la comunicación, considerándose un socket como la abstracción de este
extremo.
43
3.2 Desarrollo .NET C#
44
Un componente clave de la arquitectura .NET son los servicios Web, que son
componentes de software reutilizables que pueden usarse a través de Internet. Los clientes y
otras aplicaciones pueden usar los servicios Web como bloques de construcción
reutilizables.
Obtener acceso y mostrar datos. Describe cómo interactuar con bases de datos.
45
Programación en Tablet PC. Describe el desarrollo de aplicaciones basadas en
tinta para Tablet PC.
Crear Starter Kits. Describe cómo crear Starter Kits para ayudar a otros a
ponerse rápidamente en marcha con su código de ejemplo.
Las aplicaciones Windows Form, son aquellas basadas en ventanas y controles comunes de
Windows que se ejecutan en local. En la plataforma .NET el espacio de nombres que ofrece
las clases necesarias para construir aplicaciones de escritorio bajo Windows se denomina
Windows Forms. Este es también el nombre genérico que se le otorga ahora este tipo de
programas basados en ventanas.
Los formularios Windows Forms son la tecnología que se utiliza en Visual C# para crear
aplicaciones para clientes inteligentes basadas en Windows que se ejecutan en .NET
Framework. Cuando crea un proyecto de aplicación para Windows, está creando una
aplicación basada en formularios Windows Forms. Utilizará el Diseñador de Windows
Forms para crear la interfaz de usuario y tendrá acceso a otras funciones de diseño y tiempo
de ejecución:
a. Implementación ClickOnce.
46
El modelo de evento de .NET Framework se basa en la existencia de un delegado de
eventos que conecte un evento a su controlador. Para provocar un evento, se
requieren dos elementos:
El delegado es un tipo que define una firma, es decir, el tipo del valor devuelto y los
tipos de lista de parámetros de un método. Se puede utilizar el tipo de delegado para
declarar una variable que puede hacer referencia a cualquier método con la misma
firma que el delegado.
Para asociar el evento al método que lo controlará, hay que agregar una instancia
del delegado al evento. Siempre que se produce el evento, se llama al controlador de
eventos, a menos que se quite el delegado.
3.3.1 Descripción
4
Desarrollado por la empresa Konnetic
47
manejo de entidades y elementos que componen el protocolo SIP, dejando como resultado
una biblioteca de clases muy potente para el desarrollo de aplicaciones orientadas a
Software SIP.
El código fuente está escrito en su totalidad sobre Microsoft .NET 2.0 Framework, y corre
en sus versiones 2.0, 3.0, 3.5 y 4.0.
Muchos de los requisitos y demandas para el desarrollo de aplicaciones SIP han dejado que
la biblioteca de clases SIP.NET permita al desarrollador enfocarse en el diseño de
algoritmos orientados a la programación a alto nivel. Pero al mismo tiempo, sigue
permitiendo configuraciones y control de flujo sobre los mensajes SIP a bajo nivel basado
en eventos. Dando como resultado una pila SIP que contiene todas las funciones y servicios
necesarios para el desarrollo estructurado de aplicaciones.
Los SIP URI’s son una parte compleja e importante del protocolo SIP. El SDK SIP.NET
proporciona un tipo de mecanismo seguro para los elementos URI’s derivado de las
bibliotecas de clases System.Uri , System.Uri.Parser y System.Uri.Builder.
Un entorno SIP consiste en un número de entidades conectadas. Estas incluyen, UA (User
Agent), Proxy Server, Registrar Server, Redirect Server y B2BUA (Back-to-Back-User
Agent). Mediante la biblioteca de clases SIP.NET se obtienen las herramientas necesarias
para el desarrollo de este tipo de entidades, así como para implementarlas dentro de alguna
entidad comercial ya desarrollada y existente en el mercado.
Dentro del SDK SIP .NET existen términos que conceptualizan los procesos existentes en
una aplicación orientada a SIP. A continuación se describen algunos de ellos.
Connection. Se sabe que una conexión es una asociación entre dos puntos finales
que lleva paquetes de datos a través de una red. Cada punto final se representa por
una dirección IP y un puerto, en SIP este concepto es referido como un flujo, en la
unidad SIP .NET API (Figura n), una conexión puede utilizar TLS, TCP o UDP
dentro de la capa de transporte.
La unidad SIP .NET API admite dos tipos de conexiones: entrada y salida. Una
conexión de entrada esta a la escucha de paquetes entrantes en un extremo local
asignado. Las conexiones de salida inician las transmisiones en un extremo local
asignado. Las conexiones de salida suelen utilizar un número de puerto efímero, y
posteriormente, escuchar en ese puerto las respuestas.
50
Figura 13: Arquitectura general de la Unidad SIP.NET API
La unidad SIP .NET API se basa en ciertos recursos externos para su operación. Estos
recursos deben estar disponibles en tiempo de ejecución y los permisos de control de acceso
se deben establecer a fin de que acceda a ellos el subproceso (thread) en ejecución. Los
recursos incluyen:
Sockets. La biblioteca SIP .NET es una biblioteca en red y requiere un acceso
ilimitado a sockets dentro de ella.
Archivo IO. La biblioteca SIP.NET debe tener permisos para leer el fichero de
configuración y cualquier otro archivo enlazado dinámicamente.
La Unidad SIP.NET API hace un uso extensivo de hilos (Threads). La biblioteca utiliza llamadas
asíncronas cuando sea posible. El trabajo con hilos se utiliza para invocar la aplicación encargada
de la devolución de llamadas y algunos eventos colocados en subprocesos independientes donde
las respuestas son demandadas.
52
3.4 Configuración objeto SIP Core
El objeto SIP Core es la fachada de la biblioteca SIP.NET (a veces llamado una clase
agregada). Expone importantes eventos, puede controlar los métodos y comportamientos
más significativos de la biblioteca, así como establecer la configuración del sistema y otros
recursos utilizados. El núcleo SIP representado por el objeto SIP Core también se encarga
de la inicialización y terminación de las diferentes capas. El núcleo SIP proporciona un
modelo de eventos que controlan el proceso de entrada y los mensajes salientes, el
procesamiento subsecuente de fallos en la capa de transporte, así como la autenticación y el
estado de datos.
Propiedades.
o LocalAddressPort. Utilizado por el MessageTransmitter para especificar el
campo de cabecera Via, que para fines de la aplicación será el punto final
donde los mensajes serán devueltos, especificando estos parámetros en la
propiedad “Sentby”. Una aplicación puede proporcionar un nombre de
dominio completo o una dirección IP, si este campo está vacío, el valor por
defecto será la dirección IP local.
o Transport Layer. La propiedad SipTransportLayer se encarga de gestionar la
transmisión de mensajes hacia y desde la red en nombre del objeto SIP Core
reservado en memoria.
o Sip Transaction State. La propiedad SipTransactionStateManager se encarga
de la gestión del estado transaccional y de diálogo, en nombre del objeto SIP
Core.
5
Para el correcto funcionamiento es necesario el uso de una licencia con costo adicional.
53
o ClientCertificates. La transmisión de mensajes TLS requiere que los clientes
proporcionen un certificado para el servidor y establecer una autenticación
mutua. La propiedad ClientCertificates se copia directamente a la propiedad
SipTransportLayer.
o MultiHeaderFormat. El valor de esta propiedad indica si la biblioteca SIP
debe separar múltiples valores de encabezados en las líneas que sean
posibles.
3.5 Trixbox
3.6.3 Descripción
Los Softphones son teléfonos implementados por software, son programas informáticos que
simulan las funcionalidades de un teléfono convencional, pero ayudados de dos periféricos
habituales: micrófono y auriculares; estos últimos dispositivos, conectados a una
computadora, permiten que la voz pueda ser tratada por el Softphone y así, ser
transformada en paquetes IP.
6
Distribución de Asterisk basado Software libre
54
Se pueden encontrar modelos que funcionen bajo diferentes protocolos, aunque el mas
usado es el SIP. Entre ellos el más popular es el X-lite, aunque también existen muchos
otros que presentan buenas funcionalidades.
3.6.4 X-lite
X-Lite fue desarrollado por CounterPath, y es el principal Softphone libre SIP del mercado
disponible para la transferencia directa.
1. Una vez instalado el Softphone (por ser software libre puede ser descargado de la
página del fabricante CounterPath), se procede a hacer la configuración pertinente.
2. Seleccionamos “SIP Account Settings” y aparecerá la pantalla de la figura 14,
oprima “Add”.
Para agregar una cuenta SIP se deben introducir ciertos parámetros como se muestra en la
figura 15.
55
Figura 15. Propiedades de configuración de una cuenta SIP
56
Figura 16. Configuración de cliente SIP
Una vez realizado este proceso, el Softphone X-lite está listo para realizar y recibir
llamadas (Figura 18).
57
Figura 18. Teléfono registrado y autenticado
58
Capítulo IV Desarrollo
Una vez reunidas las herramientas necesarias para realizar el Proxy PBX, se inicia
el desarrollo de una aplicación basada en un entorno orientado a Windows, que llevará el
control y gestión de los procesos necesarios para el registro y subscripción de clientes SIP
así como la iniciación y finalización de llamadas SIP.
Tomando en cuenta que para el envío de paquetes a nivel de transporte existen dos
enfoques principales necesarios para la comunicación entre aplicaciones, se encuentran las
orientadas a conexión y no orientadas a conexión. En las comunicaciones orientadas a
conexión, se establece una conexión que se mantiene durante el tiempo que dure la sesión.
Los servicios sin conexión no garantizan confiabilidad, los datos pueden tomar rutas
distintas dentro del sistema, llegar después o no llegar.
Para fines de esta aplicación, emplearemos el protocolo UDP. Las llamadas que
cursan sobre una red de datos no requieren de la garantía de transmisión confiable de un
extremo a otro, ya que en una conversación telefónica no es necesaria la retransmisión de
voz. UDP incurre en una mínima sobrecarga, necesaria para la comunicación entre
aplicaciones, además de reducir el tráfico debido a la ausencia de intercambio,
retransmisiones, etc.
Aplicaciones como audio y video en tiempo real pueden tolerar la pérdida ocasional
de datagramas, cuando esto sucede se produce una pequeña pausa en el audio o video que
se esté reproduciendo.
Para la aplicación servidor, se utiliza un objeto de tipo TcpListener que tiene la capacidad
de esperar solicitudes de conexión, a este objeto se le asocia un número de puerto y una
dirección IP especifica, representada por un objeto de la clase IPAddress, del espacio de
nombres System.Net.
El servidor escucha de forma indefinida, hasta que un cliente trata de conectarse con el, el
servidor crea una conexión con el cliente cuando este le envía una solicitud de conexión.
59
1 public void EjecutarServidor()
2 {
3 TcpListener oyente;
4 int contador = 1;
5
6 //espera la conexion de un cliente y muestra el texto que envía el cliente
7 try
8 { //crea TcpListener
9 IPAddress local = IPAddress.Parse("1.1.1.1");
10 oyente = new TcpListener(local, 50000);
11
12 //TcpListener espera la solicitud de conexion
13 oyente.Start();
14
15 //establece la conexion con base a la solicitud del cliente
16 while (true)
17 {
18 MostrarMensaje("Esperando Conexión\r\n");
19
20 //acepta una conexion entrante
21 conexion = oyente.AcceptSocket();
22
23 //crea objeto NetworkStream asociado con el socket
24 socketStream = new NetworkStream(conexion);
25
26 //crea objetos para transferir datos a través de un flujo
27 escritor = new BinaryWriter(socketStream);
28 lector = new BinaryReader(socketStream);
29
30 MostrarMensaje("Conexión " + contador + " recibida\r\n");
31
32 //Informa al cliente que la conexión fue existosa
33 escritor.Write("SERVIDOR>> Conexión Existosa");
34
35
36 DeshabilitarEntrada(false); //habilita la entrada de datos del cliente
37
38 string larespuesta = "";
39
40 //Lee los datos de cadena que envía el cliente
41
42 do
43 {
44 try
45 {
46 //lee la cadena que envía el cliente
47 larespuesta = lector.ReadString();
48
49 //muestra el mensaje
50 MostrarMensaje("\r\n" + larespuesta);
51 }//fin de try
52 catch (Exception)
53 {
54 //maneja la excepción si hay error al leer los datos
55 MostrarMensaje("\r\n Error al leer los datos delcliente\r\n");
56 break;
57 }//fin de catch
58 } while (larespuesta != "CLIENTE>>TERMINAR" &&
60
59 conexion.Connected);
60
61 MostrarMensaje("\r\nEl Cliente terminó la comunicación\r\n");
62
63 //Se cierra la comunicación
64 escritor.Close();
65 lector.Close();
66 socketStream.Close();
67 conexion.Close();
68
69 DeshabilitarEntrada(true); //Deshabilita la entrada de datos
70 del cliente entradaTextBox
71 contador++;
72 }//fin de while
73 }//fin de try
61
Por otro lado, para la aplicación cliente, es necesario crear un objeto de la clase TcpClient
(espacio de nombres System.Net.Sockets) para realizar la conexión con el servidor. La
conexión se establece al llamar al método Connect de TcpClient.
62
La condición de paro necesaria para el fín de la comunicación, estará controlada por la
cadena “SERVIDOR>>TERMINAR”. En ese momento se liberan recursos y se finaliza el
proceso Socket.
63
4.2 Captura y análisis de Mensajes SIP
Como parte del análisis de protocolos en red, se utilizó una herramienta orientada al
monitoreo de tráfico en la red7, la siguiente imagen es captado mediante un sniffer de
código abierto encargado de capturar los paquetes SIP utilizado en el proceso de
comunicación entre Softphone – Proxy y Proxy – PBX.
Como se menciono anteriormente existen peticiones y respuestas que forman parte del
proceso de comunicación Cliente - Servidor y Cliente – Cliente. Para el caso de la
autenticación de un teléfono IP basado en Software o cualquier teléfono soportado por la
tecnología VoIP, se hace referencia a las siguientes peticiones y respuestas SIP.
7
Analizador de tráfico distribuido por The Wireshark Team.
64
Como primer proceso de autenticación, es necesario que un cliente se encuentre alojado en
un servidor de registro, proporcionándole un nombre de usuario, contraseña y un nombre de
autorización para iniciar sesión.
Para que el cliente tenga una localización física es necesario que envíe estos parámetros a
través de la trama REGISTER, esperando una contestación satisfactoria mediante una
respuesta OK con 1 Binding llamado así al proceso de conexión entre Cliente- Servidor.
La funcionalidad del Proxy PBX durante este proceso, es decidir el rumbo de la trama,
esperando la localización física del usuario mediante un servidor de registro. Obteniendo
así, la captación de todo el tráfico, y esperando un enrutamiento adecuado hacia el destino
final asociándole una dirección IP y un puerto para futuras conexiones.
65
El proceso de autenticación y registro se muestra en el siguiente diagrama (Figura 23).
El cliente Softphone envía nuevamente una trama REGISTER incluyendo las credenciales
necesarias para ser registrado y autenticado. Al llegar dichos parámetros al PBX envía una
respuesta de estado completo OK (1 Binding) indicando al cliente su localización física y
registro. Al ser registrado satisfactoriamente, el PBX necesita conocer información acerca
de la capacidad del cliente para soportar ciertos servicios y funcionalidades necesarias para
el proceso de comunicación, para esto el PBX envía una trama OPTIONS incluyendo estos
parámetros, retransmitiendo las veces que sean necesarias para conocer el estado del cliente
Softphone.
Siguiendo con el proceso de registro, el cliente solicita al PBX una subscripción, iniciando
este proceso con el envío de una trama SUBSCRIBE, que incluirá los parámetros que
requiere el cliente para entrar en un estado de suscripción. Siguiendo la misma
metodología, el PBX solicita sus credenciales para completar el proceso, y aquí
nuevamente el Proxy PBX encamina los datos hasta el cliente. Una vez solicitadas al
cliente las credenciales de suscripción, retransmite la trama SUBSCRIBE incluyendo los
parámetros solicitados y concluyendo con estado completo OK.
66
Finalmente el PBX envía una trama NOTIFY que indica un estado de notificación,
necesaria para que el cliente conozca su ubicación y propiedades con las que fue registrado
suscrito.
Las transacciones tienen un cliente y un servidor. El lado del cliente se conoce como
una transacción cliente y del lado del servidor como una transacción servidor. La
operación cliente envía la solicitud, y la transacción servidor envía la respuesta.
Las transacciones cliente y servidor son funciones lógicas que están incrustadas en
cualquier número de elementos. En concreto, existen dentro de los agentes de usuario y los
servidores Proxy de estado.
Dentro de la biblioteca de clases explicada en la sección 3.3, es posible crear objetos de tipo
SIP Core, capaces de generar eventos de tipo Server Transaction y Client Transaction,
estos eventos son útiles en el momento que se requiere procesar solicitudes y respuestas
para enrutarlas y así lograr comunicación entre Clientes y Servidores.
8
RFC 3261 SIP: Session Initiation Protocol, Seccion 17, pag. 122.
67
Figura 25. Diagrama de transacciones incluidas en el Proxy PBX
68
Las siguientes líneas de código, ejecutan las transacciones que serán útiles para el
proceso de comunicación mediante el Proxy PBX, con el evento ProxyPBX_Load se carga
dentro del proyecto el método general para realizar las transacciones necesarias que
ayudarán al funcionamiento del Proxy PBX.
1 private void ProxyPBX_Load(object sender, EventArgs e)
2 {
3 EjecutarTransaction();
4 }
5
6 public void EjecutarTransaction()
7 {
8 CoreServerT = new SipCore();
9 System.Net.IPAddress localAddress = System.Net.IPAddress.Parse("1.1.1.1");
10 CoreServerT.LocalAddressPort = new IPDomainPort(localAddress, 5060);
11 CoreServerT.StartListening(new IPEndPoint(localAddress, 5060),
12 TransportProtocol.Udp);
13 CoreServerT.ServerTransactionCreated += new
14 EventHandler<TransactionEventArgs>(OnServerTransactionCreated);
15 }
16
17 private void OnServerTransactionCreated(object sender, TransactionEventArgs e)
18 {
19 ServerTransaction trans = (ServerTransaction)e.Transaction;
20 if (trans.OriginalRequest.Method == SipMethod.Register)
21 {
22 CoreClientT = null;
23 CoreClientT = new SipCore();
24 System.Net.IPAddress localAddress =
25 System.Net.IPAddress.Parse("1.1.1.1");
26 CoreClientT.LocalAddressPort = new IPDomainPort(new
27 IPEndPoint(localAddress, 5060));
28
29 SipRequest RegisterRequest = e.Transaction.OriginalRequest;
30 RegisterRequest.RemoveHeader("Via");
31 ViaHeaderField FieldVia = new ViaHeaderField(new
32 IPDomainPort(System.Net.IPAddress.Parse("1.1.1.1"), 5060));
33 FieldVia.Branch = ViaHeaderField.NewBranch();
34 FieldVia.ProtocolName = "UDP";
35 FieldVia.ProtocolVersion = "2.0";
36 FieldVia.SentBy = new
37 IPDomainPort(System.Net.IPAddress.Parse("1.1.1.1"), 5060);
38 RegisterRequest.AddHeader(FieldVia);
39 ClientTransaction transaction =
40 SipTransaction.CreateClientTransaction(RegisterRequest, CoreClientT,
41 true);
42 RegisterRequest.SetTransaction(transaction);
43 RegisterRequest.ResponseReceived += new
44 EventHandler<ResponseReceivedEventArgs>(OnRegisterResponseReceived);
45 CoreClientT.SendRequest(RegisterRequest);
46 }
47
48 if (trans.OriginalRequest.Method == SipMethod.Subscribe)
49 {
50 CoreClientT = null;
51 CoreClientT = new SipCore();
52 System.Net.IPAddress localAddress =
53 System.Net.IPAddress.Parse("1.1.1.1");
69
54 CoreClientT.LocalAddressPort = new IPDomainPort(new
55 IPEndPoint(localAddress, 5060));
56
57 SipRequest SubscribeRequest = e.Transaction.OriginalRequest;
58 SubscribeRequest.RemoveHeader("Via");
59 ViaHeaderField FieldVia = new ViaHeaderField(new
60 IPDomainPort(System.Net.IPAddress.Parse("1.1.1.1"), 5060));
61 FieldVia.Branch = ViaHeaderField.NewBranch();
62 FieldVia.ProtocolName = "UDP";
63 FieldVia.ProtocolVersion = "2.0";
64 FieldVia.SentBy = new
65 IPDomainPort(System.Net.IPAddress.Parse("1.1.1.1"), 5060);
66 SubscribeRequest.AddHeader(FieldVia);
67 ClientTransaction transaction =
68 SipTransaction.CreateClientTransaction(SubscribeRequest, CoreClientT,
69 true);
70 SubscribeRequest.SetTransaction(transaction);
71 SubscribeRequest.ResponseReceived += new
72 EventHandler<ResponseReceivedEventArgs>
73 (SubscribeRequest_ResponseReceived);
74 CoreClientT.SendRequest(SubscribeRequest);
75 }
Para este propósito, se hace uso de la extensa variedad de clases contenidas en el SDK para
protocolo SIP (sección 3.3). Entre ellas la clase principal SIP CORE que generará los
procesos necesarios para el procesamiento de múltiples peticiones y respuestas. Dentro de
esta misma clase, se permite el envío de paquetes definidos para cada propósito, teniendo la
tarea de construir tramas para los métodos solicitados. Por otro lado, tomando respuestas
asociadas a una petición será necesario el manejo de datos de una manera estructurada,
utilizando listas enlazadas se almacenarán parámetros necesarios para la gestión de la
comunicación.
70
En la siguiente figura se muestra la estructura general de un nodo incluido en una
lista necesaria para la asociación entre peticiones y respuestas relacionadas con un UAC.
Dentro de este nodo será necesario actualizar los parámetros en tiempo de ejecución en
función de las peticiones y respuestas asociadas con cada UAC. Para la declaración de
instancias dentro de la clase NodoListaSoftphone, se construyó la siguiente estructura,
mostrada en la figura Sección de código 4:
71
39 set { Username = value; }
40 }
41 public string DIRECCIONIP
42 {
43 get { return DireccionIP; }
44 set { DireccionIP = value; }
45 }
46 public string PUERTO
47 {
48 get { return Puerto; }
49 set { Puerto = value; }
50 }
51 public string VIA
52 {
53 get { return Via; }
54 set { Via = value; }
55 }
56 public NodoListaSoftphone SIGUIENTE
57 {
58 get { return siguiente; }
59 set { siguiente = value; }
60 }
61 }
Dentro de esta clase también contiene los miembros necesarios para el control de
enrutamiento de peticiones y respuestas. Para ello se definen las propiedades DisplayName,
Username, DireccionIP, Puerto y Vía.
La propiedad DireccionIP define una dirección lógica IPv4 utilizada para la identificación
única a nivel de capa de red para cada teléfono, con esta propiedad el Proxy PBX, en
función de peticiones o respuestas, elegirá el destino adecuado.
La propiedad Puerto define un valor asociado a un cliente a nivel de capa de transporte, por
el se envían las peticiones iniciales y se espera que ahí sean contestadas con el fin de evitar
la pérdida de datos. Para el propósito en particular del proyecto, cada cliente Softphone
72
dispone de un rango de puertos efímeros disponibles para la comunicación, definidos en el
protocolo UDP.
Por último, se define la propiedad Vía que contendrá el campo de cabecera existente en la
trama SIP, que será actualizado junto con las demás propiedades cada que inicie una nueva
petición el UAC.
Una vez registrados los clientes con el PBX a través del Proxy PBX, se inicia el proceso de
comunicación a través de la trama INVITE, donde un cliente solicita establecer sesión con
un usuario final, para esto, la aplicación desarrollada será capaz de verificar si el usuario
final se encuentra en disponibilidad de aceptar una llamada, o en otro caso, verificar si
existe o no el usuario final.
El cliente Softphone1 Xlite inicia la sesión enviando una trama INVITE al objeto SIP
CORE que será el encargado de enrutar las llamadas a un destino final, la aplicación Proxy
PBX internamente trabaja con un objeto de este tipo para iniciar las transacciones
necesarias y localizar dentro de la red al Softphone Xlite. La ejecución de este proceso
estará en función de las peticiones realizadas al objeto SIP CORE tomando como parámetro
principal que el método recibido dentro de la petición está relacionado con el método SIP
INVITE. En la sección de código 5 se explica el reconocimiento del método para este
proceso y la ejecución de envío y recepción de tramas relacionadas con el inicio de sesión.
73
1 if (trans.OriginalRequest.Method == SipMethod.Invite)
2 {
3 InviteServerTransaction InviteTrans =
4 (InviteServerTransaction)e.Transaction;
5 CoreClientT = null;
6 CoreClientT = new SipCore();
7 System.Net.IPAddress localAddress =
8 System.Net.IPAddress.Parse("1.1.1.1");
9 CoreClientT.LocalAddressPort = new IPDomainPort(new
10 IPEndPoint(localAddress, 5060));
11 string CampoVia;
12 string IP;
13 string Puerto;
14 CampoVia = trans.OriginalRequest.ViaHeaders.ToString();
15 char[] sep = { ' ', ':', ';' };
16 string[] part = CampoVia.Split(sep);
17 IP = part[3];
18 Puerto = part[4];
19 string dname;
20 string username;
21 char[] tok = { '"', '"', ':', '@' };
22 string from = trans.OriginalRequest.From.ToString();
23 string[] part2 = from.Split(tok);
24 dname = part2[2];
25 username = part2[4];
26 listaCliente.Insertar(dname, username, IP, Puerto, Via);
27 listaRegistro.Insertar(username, IP, Puerto);
28 char[] tok2 = { ':', '@' };
29 string To = trans.OriginalRequest.RequestUri.AbsoluteUri.ToString();
30 string[] part3 = To.Split(tok);
31 string usernameDestino = part3[1];
32 string callIDpar = trans.OriginalRequest.CallId.ToString();
33 string[] parametros = listaRegistro.Buscar(usernameDestino);
34 string DNDestino = trans.OriginalRequest.To.DisplayName.ToString();
35 string Fecha = DateTime.Now.Date.ToString();
36
37 SipResponse RingingResponse = new
38 SipResponse(InviteTrans.OriginalRequest, SipStatusCode.Ringing);
39 System.Net.IPAddress RemoteAddress = System.Net.IPAddress.Parse(IP);
40 DestinationTuple destination = new DestinationTuple(new
41 IPEndPoint(RemoteAddress, int.Parse(Puerto)), TransportProtocol.Udp);
42 CoreServerT.SendResponseDirect(RingingResponse, destination);
43 listaReportes.Insertar(callIDpar, dname, username, IP, DNDestino,
44 usernameDestino, parametros[1], Fecha);
45
46 InviteRequest Invite = new InviteRequest();
47 ViaHeaderField FieldVia = new ViaHeaderField(new
48 IPDomainPort(System.Net.IPAddress.Parse("1.1.1.1"), 5060));
49 FieldVia.Branch = ViaHeaderField.NewBranch();
50 FieldVia.ProtocolName = "UDP";
51 FieldVia.ProtocolVersion = "2.0";
52 FieldVia.SentBy = new
53 IPDomainPort(System.Net.IPAddress.Parse("1.1.1.1"), 5060);
54 Invite.AddHeader(FieldVia);
74
Para que un cliente destino localice el usuario fuente, será necesario que el Proxy PBX
envíe la señalización necesaria para el inicio de sesión, como se muestra en la sección de
código 4, el objeto SIP CORE hace un criterio de análisis para determinar si la transacción
Servidor reconoce un método de tipo INVITE, si esta condición se cumple, envía como
respuesta inmediata una trama de procedimiento 180 (RINGING), que será llevada a un
estado de completo con un OK para indicar que la sesión fue aceptada por el cliente
destino.
La base de datos consiste en una tabla que almacenará en tiempo real, las llamadas
cursan sobre la red. En la siguiente figura, se muestra la tabla que se creó con los campos
pertinentes para realizar el reporte de llamadas.
75
Capítulo V Pruebas
Objetivo
76
Figura 30. Esquema SIP de registro y autenticación de Softphone
5.1.1 Resultados
Como resultado a esta primera etapa de la realización del proyecto, se obtuvo el cliente
Softphone XLite, registrado con el nombre de usuario 40 (figura 31).
77
De esta forma, también se capturo información del usuario registrado a través del Log de
Tramas (Figura 32).
Objetivo
El objetivo de esta etapa, es el establecer una sesión SIP entre dos clientes
Softphone que iniciaran y terminaran una llamada telefónica. El cliente Softphone 1 con
dirección SIP URI [email protected], realiza una llamada al cliente Softphone 2 con SIP URI
[email protected], en la figura 33 se muestra el diagrama Establecimiento y liberación de sesión
SIP.
78
Por otra parte, el método SIP INVITE contiene el protocolo SDP (Session Description
Protocol), que esta encargado de definir las características media que el que inicia la
llamada necesita para realizarla.
79
5.2.1 Resultados
Como resultado a esta prueba, se obtuvo mediante el Log de Tramas información de origen
y destino de la llamada, direcciones IP, puertos utilizados, entre otros campos (Figura 35).
80
Figura 36. Softphone2 Figura 37. Llamada establecida
Objetivo
81
5.3.1 Resultados
82
Figura 41. Créditos
83
Conclusiones
Los alcances de este proyecto y algunas de las mejoras que podrían hacerse es la
extensión de las funciones del Proxy PBX IP para ser reportes de llamadas de la PSTN, así
como la implementación de restricciones de las llamadas, distribuir permisos y llevar un
control más preciso del tráfico de llamadas de la red.
84
Glosario
PBX. Private Branch Exchange, Una PBX se encarga de establecer conexiones entre
terminales de una misma empresa, o de hacer que se cursen llamadas al exterior. Hace que
las extensiones tengan acceso desde el exterior, desde el interior, y ellas a su vez tengan
acceso también a otras extensiones y a una línea externa.
Proxy. El servidor proxy como en la mayoría de los casos actúa como un intermediario que
de un UAC a los UAS, o bien, otras UACs. Un Servidor Proxy puede ser utilizado para
encaminar las comunicaciones SIP, también se puede utilizar para la localización de una
identidad SIP.
PSTN. Public Switched Telephone Network, es una red con conmutación de circuitos
tradicional optimizada para comunicaciones de voz en tiempo real. Cuando llama a alguien,
cierra un conmutador al marcar y establece así un circuito con el receptor de la llamada.
UAC. User agent client, es una aplicación que inicia hasta seis posibles peticiones SIP a un
UAS .Las seis peticiones formuladas por la UAC son: INVITE, ACK, OPTIONS, BYE,
CANCEL y REGISTER.
UAS. UAS es el servidor que aloja la aplicación encargada de recibir las solicitudes SIP de
un UAC, y en la recepción devuelve una respuesta a la solicitud de nuevo a la UAC. La
UAS puede emitir respuestas múltiples a la UAC, no necesariamente una sola respuesta. La
comunicación entre UAC y UAS es cliente / servidor y (peer-to-peer).
VoIP. Es la abreviación en inglés de Voice over IP (Voz sobre IP o voz sobre protocolo de
Internet), y se usa para identificar la tecnología detrás de comunicaciones usando voz y vídeo
a través de Internet.
85
Anexo I
Código
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Konnetic.Signalling.Sip;
using Konnetic.Signalling.Sdp;
using Konnetic.Net.Transport;
namespace ProxyPBX
{
public partial class ProxyPBX : Form
{
private delegate void UpdateTextCallback(string text);
private DateTime Hora;
private DateTime Fecha;
private string HoraC;
private string FechaC;
private SipCore CoreServerT = null;
private SipCore CoreClientT = null;
private SipCore CoreServerTOptions = null;
private SipCore CoreServerTNotify = null;
string CampoViaRegister;
string CampoViaOptions;
string CampoViaSubscribe;
string CampoViaNotify;
string CampoViaInvite;
ListaSoftphone listaCliente = new ListaSoftphone();
ListaTrixBox listaServidor = new ListaTrixBox();
ListaRegistro listaRegistro = new ListaRegistro();
ListaReportes listaReportes = new ListaReportes();
86
ListaCallID listaCallID = new ListaCallID();
private Panel buttonPanel = new Panel();
private DataGridView ReporteadorDataGridView = new DataGridView();
private Button addNewRowButton = new Button();
private Button deleteRowButton = new Button();
public ProxyPBX()
{
InitializeComponent();
}
CoreServerT.ServerTransactionCreated += new
EventHandler<TransactionEventArgs>(OnServerTransactionCreated);
}
string CampoVia;
string IP;
string Puerto;
string dname;
string username;
CampoVia = trans.OriginalRequest.ViaHeaders.ToString();
char[] sep = { ' ', ':', ';' };
87
string[] part = CampoVia.Split(sep);
char[] tok = { '"', '"', ':', '@' };
string from = trans.OriginalRequest.From.ToString();
string[] part2 = from.Split(tok);
IP = part[3];
Puerto = part[4];
dname = part2[2];
username = part2[4];
listaCliente.Insertar(dname, username, IP, Puerto, CampoVia);
listaRegistro.Insertar(username, IP, Puerto);
Append("");
Append("Trama REGISTER");
Append("Campo Via: " + CampoVia);
Append("Username: " + username);
Append("Displayname: " + dname);
Append("Dirección IP: " + IP);
Append("Puerto: " + Puerto);
SipRequest RegisterRequest = e.Transaction.OriginalRequest;
if (RegisterRequest.AuthorizationHeaders != null)
{
Append("Credenciales: " + RegisterRequest.AuthorizationHeaders.ToString());
}
RegisterRequest.RemoveHeader("Via");
ViaHeaderField FieldVia = new ViaHeaderField(new
IPDomainPort(System.Net.IPAddress.Parse("1.1.1.1"), 5060));
FieldVia.Branch = ViaHeaderField.NewBranch();
FieldVia.ProtocolName = "UDP";
FieldVia.ProtocolVersion = "2.0";
FieldVia.SentBy = new IPDomainPort(System.Net.IPAddress.Parse("1.1.1.1"), 5060);
RegisterRequest.AddHeader(FieldVia);
ClientTransaction transaction =
SipTransaction.CreateClientTransaction(RegisterRequest, CoreClientT, true);
RegisterRequest.SetTransaction(transaction);
RegisterRequest.ResponseReceived += new
EventHandler<ResponseReceivedEventArgs>(OnRegisterResponseReceived);
CoreClientT.SendRequest(RegisterRequest);
}
if (trans.OriginalRequest.Method == SipMethod.Subscribe)
{
CoreClientT = null;
CoreClientT = new SipCore();
System.Net.IPAddress localAddress = System.Net.IPAddress.Parse("1.1.1.1");
CoreClientT.LocalAddressPort = new IPDomainPort(new
IPEndPoint(localAddress, 5060));
88
string CampoVia;
string IP;
string Puerto;
CampoVia = trans.OriginalRequest.ViaHeaders.ToString();
char[] sep = { ' ', ':', ';' };
string[] part = CampoVia.Split(sep);
IP = part[3];
Puerto = part[4];
string Via = trans.OriginalRequest.ViaHeaders.ToString();
string dname;
string username;
char[] tok = { '"', '"', ':', '@' };
string from = trans.OriginalRequest.From.ToString();
string[] part2 = from.Split(tok);
dname = part2[2];
username = part2[4];
listaCliente.Insertar(dname, username, IP, Puerto, Via);
listaRegistro.Insertar(username, IP, Puerto);
Append("");
Append("Trama SUBSCRIBE");
Append("Campo Via: " + CampoVia);
Append("Username: " + username);
Append("Displayname: " + dname);
Append("Dirección IP: " + IP);
Append("Puerto: " + Puerto);
SipRequest SubscribeRequest = e.Transaction.OriginalRequest;
if (SubscribeRequest.AuthorizationHeaders != null)
{
Append("Credenciales: " +
SubscribeRequest.AuthorizationHeaders.ToString());
}
SubscribeRequest.RemoveHeader("Via");
ViaHeaderField FieldVia = new ViaHeaderField(new
IPDomainPort(System.Net.IPAddress.Parse("1.1.1.1"), 5060));
FieldVia.Branch = ViaHeaderField.NewBranch();
FieldVia.ProtocolName = "UDP";
FieldVia.ProtocolVersion = "2.0";
FieldVia.SentBy = new IPDomainPort(System.Net.IPAddress.Parse("1.1.1.1"),
5060);
SubscribeRequest.AddHeader(FieldVia);
ClientTransaction transaction =
SipTransaction.CreateClientTransaction(SubscribeRequest, CoreClientT, true);
SubscribeRequest.SetTransaction(transaction);
SubscribeRequest.ResponseReceived += new
89
EventHandler<ResponseReceivedEventArgs>(SubscribeRequest_ResponseReceived);
CoreClientT.SendRequest(SubscribeRequest);
}
if (e.Transaction.OriginalRequest.Method == SipMethod.Invite)
{
InviteServerTransaction InviteTrans = (InviteServerTransaction)e.Transaction;
CoreClientT = null;
CoreClientT = new SipCore();
System.Net.IPAddress localAddress = System.Net.IPAddress.Parse("1.1.1.1");
CoreClientT.LocalAddressPort = new IPDomainPort(new
IPEndPoint(localAddress, 5060));
string CampoVia;
string IP;
string Puerto;
CampoVia = trans.OriginalRequest.ViaHeaders.ToString();
char[] sep = { ' ', ':', ';' };
string[] part = CampoVia.Split(sep);
IP = part[3];
Puerto = part[4];
string dname;
string username;
char[] tok = { '"', '"', ':', '@' };
string from = trans.OriginalRequest.From.ToString();
string[] part2 = from.Split(tok);
dname = part2[2];
username = part2[4];
listaCliente.Insertar(dname, username, IP, Puerto, CampoVia);
listaRegistro.Insertar(username, IP, Puerto);
Append("");
Append("TRAMA: INVITE");
Append("USUARIO FUENTE:");
Append("Campo Via: " + CampoVia);
Append("Username: " + username);
Append("Displayname: " + dname);
Append("Dirección IP: " + IP);
Append("Puerto: " + Puerto);
if (parametros != null)
{
listaReportes.Insertar(dname, username, IP, DNDestino, usernameDestino,
parametros[1], HoraInicio, Fecha);
if (trans.OriginalRequest.Method == SipMethod.Bye)
{
//Response ByeResponse = Servidor.SendResponseOK(e.Request);
//Servidor.Bye(ByeResponse);
}
}
92
private void OnRegisterResponseReceived(object sender,
ResponseReceivedEventArgs e)
{
int port;
if (e.Response.StatusClass == SipStatusClass.Successful)
{
Append("ESTADO: " + "REGISTER OK===");
char[] tok = { '=', ' ' };
string via = e.Response.ViaHeaders.ToString();
string[] part = via.Split(tok);
port = int.Parse(part[5]);
string dname;
string username;
char[] tok2 = { '"', '"', ':', '@' };
string from = e.Response.From.ToString();
string[] part2 = from.Split(tok2);
dname = part2[2];
username = part2[4];
string[] parametros = listaCliente.Buscar(dname, username);
System.Net.IPAddress RemoteAddress =
System.Net.IPAddress.Parse(parametros[2]);
DestinationTuple destination = new DestinationTuple(new
IPEndPoint(RemoteAddress, int.Parse(parametros[3])), TransportProtocol.Udp);
CampoViaRegister = parametros[4];
SipResponse RespRegisterServerT = e.Response;
RespRegisterServerT.RemoveHeader("Via");
RespRegisterServerT.ViaHeaders.Add(CampoViaRegister);
CoreServerT.SendResponseDirect(RespRegisterServerT, destination);
listaCliente.Eliminar(dname, username);
CoreServerTOptions = null;
CoreServerTOptions = new SipCore();
CoreServerTOptions.StartListening(new
IPEndPoint(System.Net.IPAddress.Parse("1.1.1.1"), port), TransportProtocol.Udp);
CoreServerTOptions.ServerTransactionCreated += new
EventHandler<TransactionEventArgs>(CoreServerTOptions_NewPort);
}
else
{
Append("ESTADO: " + "REGISTER "+ e.Response.StatusLine.ToString());
string dname;
string username;
char[] tok2 = { '"', '"', ':', '@' };
string from = e.Response.From.ToString();
string[] part2 = from.Split(tok2);
dname = part2[2];
username = part2[4];
string[] parametros = listaCliente.Buscar(dname, username);
93
System.Net.IPAddress RemoteAddress =
System.Net.IPAddress.Parse(parametros[2]);
DestinationTuple destination = new DestinationTuple(new
IPEndPoint(RemoteAddress, int.Parse(parametros[3])), TransportProtocol.Udp);
CampoViaRegister = parametros[4];
SipResponse RespRegisterServerT = e.Response;
RespRegisterServerT.RemoveHeader("Via");
RespRegisterServerT.ViaHeaders.Add(CampoViaRegister);
CoreServerT.SendResponseDirect(RespRegisterServerT, destination);
listaCliente.Eliminar(dname, username);
}
}
private void CoreServerTOptions_NewPort(object sender, TransactionEventArgs e)
{
ServerTransaction trans = (ServerTransaction)e.Transaction;
if (trans.OriginalRequest.Method == SipMethod.Options)
{
CoreClientT = null;
CoreClientT = new SipCore();
System.Net.IPAddress localAddress = System.Net.IPAddress.Parse("1.1.1.1");
CoreClientT.LocalAddressPort = new IPDomainPort(new
IPEndPoint(localAddress, 5060));
string IP;
string Puerto;
string Via = trans.OriginalRequest.ViaHeaders.ToString();
string username;
char[] tok = { ':', '@', ':', ';' };
string to = trans.OriginalRequest.To.Uri.ToString();
string[] part2 = to.Split(tok);
username = part2[1];
IP = part2[2];
Puerto = part2[3];
listaServidor.Insertar(username, IP, Puerto, Via);
SipRequest OptionsRequest = e.Transaction.OriginalRequest;
OptionsRequest.RemoveHeader("Via");
ViaHeaderField FieldVia = new ViaHeaderField(new
IPDomainPort(System.Net.IPAddress.Parse("1.1.1.1"), 5060));
FieldVia.Branch = ViaHeaderField.NewBranch();
FieldVia.ProtocolName = "UDP";
FieldVia.ProtocolVersion = "2.0";
FieldVia.SentBy = new IPDomainPort(System.Net.IPAddress.Parse("1.1.1.1"),
5060);
OptionsRequest.AddHeader(FieldVia);
ClientTransaction transaction =
SipTransaction.CreateClientTransaction(OptionsRequest, CoreClientT, true);
OptionsRequest.SetTransaction(transaction);
94
OptionsRequest.ResponseReceived += new
EventHandler<ResponseReceivedEventArgs>(OptionsRequest_ResponseReceived);
System.Net.IPAddress RemoteAddress = System.Net.IPAddress.Parse(IP);
DestinationTuple destination = new DestinationTuple(new
IPEndPoint(RemoteAddress, int.Parse(Puerto)), TransportProtocol.Udp);
CoreClientT.SendRequestDirect(OptionsRequest, destination);
}
}
private void OptionsRequest_ResponseReceived(object sender,
ResponseReceivedEventArgs e)
{
Append("TRAMA: OPTIONS");
Append("ESTADO: COMPLETADO");
string username;
char[] tok2 = { '"', '"', ':', '@' };
string to = e.Response.To.Uri.ToString();
string[] part2 = to.Split(tok2);
username = part2[1];
string[] parametros = listaServidor.Buscar(username);
CampoViaOptions = parametros[3];
}
if (e.Response.StatusCodeNumber == 401)
{
Append("ESTADO: SUBSCRIBE UNAUTHORIZED");
string dname;
string username;
char[] tok2 = { '"', '"', ':', '@' };
string from = e.Response.From.ToString();
string[] part2 = from.Split(tok2);
dname = part2[2];
username = part2[4];
string[] parametros = listaCliente.Buscar(dname, username);
System.Net.IPAddress RemoteAddress =
System.Net.IPAddress.Parse(parametros[2]);
DestinationTuple destination = new DestinationTuple(new
IPEndPoint(RemoteAddress, int.Parse(parametros[3])), TransportProtocol.Udp);
CampoViaSubscribe = parametros[4];
SipResponse RespSubscribeServerT = e.Response;
RespSubscribeServerT.RemoveHeader("Via");
RespSubscribeServerT.ViaHeaders.Add(CampoViaSubscribe);
CoreServerT.SendResponseDirect(RespSubscribeServerT, destination);
listaCliente.Eliminar(dname, username);
}
}
string IP;
string Puerto;
string Via = trans.OriginalRequest.ViaHeaders.ToString();
string username;
char[] tok = { ':', '@', ':', ';' };
string to = trans.OriginalRequest.RequestUri.AbsoluteUri.ToString();
string[] part2 = to.Split(tok);
username = part2[1];
IP = part2[2];
Puerto = part2[3];
listaServidor.Insertar(username, IP, Puerto, Via);
SipRequest NotifyRequest = e.Transaction.OriginalRequest;
NotifyRequest.RemoveHeader("Via");
ViaHeaderField FieldVia = new ViaHeaderField(new
IPDomainPort(System.Net.IPAddress.Parse("1.1.1.1"), 5060));
FieldVia.Branch = ViaHeaderField.NewBranch();
FieldVia.ProtocolName = "UDP";
FieldVia.ProtocolVersion = "2.0";
FieldVia.SentBy = new IPDomainPort(System.Net.IPAddress.Parse("1.1.1.1"),
5060);
NotifyRequest.AddHeader(FieldVia);
ClientTransaction transaction =
SipTransaction.CreateClientTransaction(NotifyRequest, CoreClientT, true);
NotifyRequest.SetTransaction(transaction);
System.Net.IPAddress RemoteAddress = System.Net.IPAddress.Parse(IP);
DestinationTuple destination = new DestinationTuple(new
IPEndPoint(RemoteAddress, int.Parse(Puerto)), TransportProtocol.Udp);
NotifyRequest.ResponseReceived += new
EventHandler<ResponseReceivedEventArgs>(NotifyRequest_ResponseReceived);
CoreClientT.SendRequestDirect(NotifyRequest, destination);
}
}
private void NotifyRequest_ResponseReceived(object sender,
ResponseReceivedEventArgs e)
{
Append("TRAMA: NOTIFY");
Append("ESTADO: COMPLETADO");
string IP;
string username;
char[] tok2 = { '"', '"', ':', '@' };
97
string to = e.Response.To.Uri.ToString();
string[] part2 = to.Split(tok2);
username = part2[1];
IP = part2[2];
string[] parametros = listaServidor.Buscar(username);
CampoViaNotify = parametros[3];
99
RespInviteServerT.AllowHeaders.Add(new
AllowHeaderField(SipMethod.Cancel));
RespInviteServerT.AllowHeaders.Add(new
AllowHeaderField(SipMethod.Bye));
RespInviteServerT.AllowHeaders.Add(new
AllowHeaderField(SipMethod.Refer));
RespInviteServerT.AllowHeaders.Add(new
AllowHeaderField(SipMethod.Subscribe));
RespInviteServerT.AllowHeaders.Add(new
AllowHeaderField(SipMethod.Notify));
RespInviteServerT.AllowHeaders.Add(new
AllowHeaderField(SipMethod.Info));
RespInviteServerT.SupportedHeaders.Add("replaces");
RespInviteServerT.SupportedHeaders.Add("timer");
SipUri URIRing = e.Response.To.Uri;
ContactHeaderField contact = new ContactHeaderField(URIRing);
RespInviteServerT.ContactHeaders.Add(contact);
CoreServerT.SendResponseDirect(RespInviteServerT, destination);
CoreClientT.StartListening(new
IPEndPoint(System.Net.IPAddress.Parse("1.1.1.1"), int.Parse(rport)),
TransportProtocol.Udp);
CoreClientT.ResponseReceived+=new
EventHandler<ResponseReceivedEventArgs>(CoreClientT_ResponseReceived);
}
}
private void CoreClientT_ResponseReceived(object sender,
ResponseReceivedEventArgs e)
{
if (e.Response.StatusClass == SipStatusClass.Successful)
{
Append("ESTADO: INVITE OK");
Append("SESION ESTABLECIDA");
//listaReportes.Mostrar();
Append(e.Response.ToString());
CoreClientT = null;
CoreClientT = new SipCore();
System.Net.IPAddress localAddress = System.Net.IPAddress.Parse("1.1.1.1");
CoreClientT.LocalAddressPort = new IPDomainPort(new
IPEndPoint(localAddress, 5060));
string usernameTo;
char[] tok = { ':', ':', '@' };
string to = e.Response.To.ToString();
string[] part1 = to.Split(tok);
usernameTo = part1[2];
string[] parametrosTo = listaRegistro.Buscar(usernameTo);
string dnameFrom;
string usernameFrom;
char[] tok2 = { '"', '"', ':', '@' };
string from = e.Response.From.ToString();
string[] part2 = from.Split(tok2);
dnameFrom = part2[2];
usernameFrom = part2[4];
string[] parametrosFrom = listaCliente.Buscar(dnameFrom, usernameFrom);
System.Net.IPAddress RemoteAddress =
System.Net.IPAddress.Parse(parametrosFrom[2]);
DestinationTuple destination = new DestinationTuple(new
IPEndPoint(RemoteAddress, int.Parse(parametrosFrom[3])), TransportProtocol.Udp);
CampoViaInvite = parametrosFrom[4];
}
public bool ListaVacia()
{
return primerNodoRegistro == null;
}
}
class NodoListaReportes
{
NodoListaReportes anterior;
public string DisplayNameOrigen;
public string UserNameOrigen;
public string IPOrigen;
public string DisplayNameDestino;
public string UserNameDestino;
public string IPDestino;
111
public string HoraInicio;
public string HoraFin;
public string Duracion;
public string Fecha;
NodoListaReportes siguiente;
public NodoListaReportes(string DisplayNameOrigen, string UserNameOrigen,
string IPOrigen, string DisplayNameDestino, string UserNameDestino, string IPDestino,
string HoraInicio, string Fecha)
: this(null, DisplayNameOrigen, UserNameOrigen, IPOrigen,
DisplayNameDestino, UserNameDestino, IPDestino, HoraInicio, null, null, Fecha, null) { }
public NodoListaReportes(NodoListaReportes anterior, string DisplayNameOrigen,
string UserNameOrigen, string IPOrigen, string DisplayNameDestino, string
UserNameDestino, string IPDestino, string HoraInicio, string HoraFin, string Duracion,
string Fecha, NodoListaReportes siguiente)
{
this.anterior = anterior;
this.DisplayNameOrigen = DisplayNameOrigen;
this.UserNameOrigen = UserNameOrigen;
this.IPOrigen = IPOrigen;
this.DisplayNameDestino = DisplayNameDestino;
this.UserNameDestino = UserNameDestino;
this.IPDestino = IPDestino;
this.HoraInicio = HoraInicio;
this.HoraFin = HoraFin;
this.Duracion = Duracion;
this.Fecha = Fecha;
this.siguiente = siguiente;
}
public NodoListaReportes ANTERIOR
{
get { return anterior; }
set { anterior = value; }
}
}
}
class NodoListaCallID
{
NodoListaCallID anterior;
public string CallID;
public string usernameOrigen;
public string usernameDestino;
NodoListaCallID siguiente;
public NodoListaCallID(string CallId, string usernameOrigen, string
usernameDestino)
: this(null, CallId, usernameOrigen, usernameDestino, null) { }
public NodoListaCallID(NodoListaCallID anterior, string CallID, string
usernameOrigen, string usernameDestino, NodoListaCallID siguiente)
{
this.anterior = anterior;
this.CallID = CallID;
this.usernameOrigen = usernameOrigen;
this.usernameDestino = usernameDestino;
this.siguiente = siguiente;
}
public NodoListaCallID ANTERIOR
{
get { return anterior; }
set { anterior = value; }
}
public string CALLID
{
get { return CallID; }
set { CallID = value; }
}
public string USERNAMEORIGEN
{
get { return usernameOrigen; }
set { usernameOrigen = value; }
}
public string USERNAMEDESTINO
{
get { return usernameDestino; }
set { usernameDestino = value; }
}
public NodoListaCallID SIGUIENTE
{
get { return siguiente; }
set { siguiente = value; }
}
}
115
public class ListaCallID
{
private NodoListaCallID primerNodoCALLID;
private NodoListaCallID ultimoNodoCALLID;
public ListaCallID()
{
primerNodoCALLID = ultimoNodoCALLID = null;
}
public void Insertar(string CallId, string usernameOrigen, string usernameDestino)
{
if (ListaVacia())
{
primerNodoCALLID = ultimoNodoCALLID = new NodoListaCallID(CallId,
usernameOrigen, usernameDestino);
}
else
{
primerNodoCALLID.ANTERIOR = primerNodoCALLID = new
NodoListaCallID(null, CallId, usernameOrigen, usernameDestino, primerNodoCALLID);
}
}
public string Buscar(string usernameOrigen, string usernameDestino)
{
NodoListaCallID Actual = primerNodoCALLID;
bool existe = false;
string identificador;
do
{
if ((Actual.USERNAMEORIGEN == usernameOrigen) &&
(Actual.USERNAMEDESTINO == usernameDestino))
{
existe = true;
break;
}
if (Actual == ultimoNodoCALLID) { break; }
Actual = Actual.SIGUIENTE;
} while (Actual != null);
if (existe == true)
{
identificador = Actual.CALLID;
return identificador;
}
else
{
identificador = null;
return identificador;
116
}
}
117
}
dataGridView1.ColumnCount = 10;
//dataGridView1.ColumnHeadersDefaultCellStyle.BackColor = Color.Navy;
//dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor = Color.White;
dataGridView1.ColumnHeadersDefaultCellStyle.Font = new
Font(ReporteadorDataGridView.Font, FontStyle.Bold);
dataGridView1.Name = "ReporteadorDataGridView";
//dataGridView1.Location = new Point(15, 426);
//dataGridView1.Size = new Size(15, 426);
//dataGridView1.AutoSizeRowsMode =
DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders;
//dataGridView1.ColumnHeadersBorderStyle =
DataGridViewHeaderBorderStyle.Single;
//dataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.Single;
//dataGridView1.GridColor = Color.Black;
//dataGridView1.RowHeadersVisible = false;
118
dataGridView1.Columns[0].Name = "DisplayNameOrigen";
dataGridView1.Columns[1].Name = "UserNameOrigen";
dataGridView1.Columns[2].Name = "IPOrigen";
dataGridView1.Columns[3].Name = "DisplayNameDestino";
dataGridView1.Columns[4].Name = "UserNameDestino";
dataGridView1.Columns[5].Name = "IPDestino";
dataGridView1.Columns[6].Name = "HoraInicio";
dataGridView1.Columns[7].Name = "HoraFin";
dataGridView1.Columns[8].Name = "Duracion";
dataGridView1.Columns[9].Name = "Fecha";
//dataGridView1.Columns[9].DefaultCellStyle.Font = new
Font(dataGridView1.DefaultCellStyle.Font, FontStyle.Italic);
//dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
//dataGridView1.MultiSelect = false;
//dataGridView1.Dock = DockStyle.Fill;
//dataGridView1.CellFormatting += new
DataGridViewCellFormattingEventHandler(dataGridView1_CellFormatting);
}
/* if (parametros != null)
{
string[] row1 = { parametros[0], parametros[1], parametros[2], parametros[3],
parametros[4], parametros[5], parametros[6], parametros[7], parametros[8], parametros[9]
};
dataGridView1.Rows.Add(row1);
}
*/
dataGridView1.Rows.Add(row1);
dataGridView1.Rows.Add(row2);
dataGridView1.Rows.Add(row3);
// }
ComandoSql.Connection = conn;
ComandoSql.ExecuteNonQuery();
conn.Close();
}
121
Bibliografía
122