Capítulo IV Desarrollo
5.2 Establecimiento y liberación de sesión SIP
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.
El mensaje de establecimiento de llamada SIP INVITE es emitido por el que llama al PROXY PBX, éste identifica la localización del que esta llamado (dirección IP) y encamina la llamada a su destino. El mensaje INVITE contiene distintos campos de cabecera obligatorios, entre los cuales están la dirección SIP URI de quien llama “From”, la dirección SIP URI de quien recibe la llamada “To”, el identificador de la llamada “Call-
ID”, el numero de secuencia “Cseq”, un numero máximo de saltos “max-forwards”.
El campo de cabecera “Via” esta actualizado por todas las entidades que participan en el enrutamiento de la llamada, esto asegura que la respuesta seguirá el mismo camino que el requerimiento.
79
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.
Figura 33. Diagrama Establecimiento y liberación de sesión SIP
En la siguiente figura, se muestra a detalle el procedimiento del envío de mensajes SIP entre los UAC, pasando por la entidad PROXY PBX para el inicio y fin de la sesión.
80
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).
Figura 35. Log de tramas inicio y fin de sesión.
La figura 36 muestra el cliente Softphone2 recibiendo la llamada del Softphone1, donde se despliega su Username (40) así como el Displayname (Liliana).
81
Figura 36. Softphone2 Figura 37. Llamada establecida
5.3 Prueba Reporteador Objetivo
Como parte final del proyecto, se implemento un servicio de reportes de llamada, donde se registra quienes establecieron comunicación dentro de la red, hora de inicio y fin de la llamada, así como la duración de la misma.
82
5.3.1 Resultados
Figura 39.Prueba Reporteador
5.4 Resultados finales
83
84
Conclusiones
El desarrollo de software basado en normas o estándares, permite conocer a fondo el funcionamiento de protocolos como en este caso: El protocolo SIP para VoIP. Se comprendió a fondo como las aplicaciones de red con las que el usuario trabaja, interactúan con los diversos protocolos que forman el modelo TCP/IP. Para programar aplicaciones de red, es necesario conocer formatos de flujo de tráfico y eventos que se disparan en función del tráfico de red. Programar protocolos de la capa de aplicación, nos permite desarrollar software adaptado a las necesidades de una empresa.
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.
Después de realizar las pruebas necesarias, se cumplieron los objetivos planteados al inicio del proyecto y se logró la creación de una herramienta muy importante de uso empresarial, basada en un protocolo (SIP) estandarizado por una organización internacional como lo es la IETF, ya que de esta forma, se podría llegar a una homologación con otras aplicaciones basadas en este estándar.
85
Glosario
Códec. Software, hardware o una combinación de ambos, capaz de transformar un archivo, un flujo de datos o una señal. Los códecs pueden codificar el flujo o la señal y recuperarlo o descifrarlo del mismo modo para la reproducción o la manipulación en un formato más apropiado para estas operaciones.
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. SIP. Session Initiation Protocol. Es un protocolo estandarizado por la Internet Engineering Task Force (IETF) para iniciar, modificar y terminar una sesión de usuario interactiva que implica elementos multimedia.
Socket. Es un método para la comunicación entre un programa del cliente y un programa del servidor en una red. Un socket se define como el punto final en una conexión. Los sockets se crean y se utilizan con un sistema de peticiones o de llamadas de función a veces llamados interfaz de programación de aplicación de sockets.
Softphone. Es un software que simula un telefono en una PC y permite hacer llamadas VoIP sin necesidad de tener un telefono IP físico. Es decir, convierte la PC en un Telefono IP para hacer llamadas a otros softphones (de PC a PC) o a otros teléfonos convencionales usando un Operador de Telefonia IP (de PC a Telefonos).
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.
86
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();
87
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(); }
private void ProxyPBX_Load_1(object sender, EventArgs e) { EjecutarTransaction(); DisDataGridView(); AReporteadorDataGridView(); }
public void EjecutarTransaction() {
CoreServerT = new SipCore();
System.Net.IPAddress localAddress = System.Net.IPAddress.Parse("1.1.1.1"); CoreServerT.LocalAddressPort = new IPDomainPort(localAddress, 5060);
CoreServerT.StartListening(new IPEndPoint(localAddress, 5060), TransportProtocol.Udp);
CoreServerT.ServerTransactionCreated += new
EventHandler<TransactionEventArgs>(OnServerTransactionCreated); }
private void OnServerTransactionCreated(object sender, TransactionEventArgs e) {
ServerTransaction trans = (ServerTransaction)e.Transac if (trans.OriginalRequest.Method == SipMethod.Register) {
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; string dname; string username; CampoVia = trans.OriginalRequest.ViaHeaders.ToString(); char[] sep = { ' ', ':', ';' };
88
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));
89 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);
90 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);
char[] tok2 = { ':', '@' };
string To = trans.OriginalRequest.RequestUri.AbsoluteUri.ToString(); Append("Campo To: " + To);
string[] part3 = To.Split(tok); string usernameDestino = part3[1];
string callIDpar = trans.OriginalRequest.CallId.ToString(); string[] parametros = listaRegistro.Buscar(usernameDestino);
string DNDestino = trans.OriginalRequest.To.DisplayName.ToString(); string Fecha = DateTime.Now.Date.ToString("d MMM yyyy");
91
Append("USUARIO DESTINO:");
Append("Username: " + usernameDestino); Append("Displayename: " + DNDestino); Append("Dirección IP: " + parametros[1]); Append("Puerto: " + parametros[2]);
Append("CallID: "+ trans.OriginalRequest.CallId.ToString()); Append("Fecha: " + Fecha);
Append("Hora Inicio: " + HoraInicio);
Append(InviteTrans.OriginalRequest.ToString());
if (parametros != null) {
listaReportes.Insertar(dname, username, IP, DNDestino, usernameDestino, parametros[1], HoraInicio, Fecha);
SipUriBuilder UriTo = new SipUriBuilder(); UriTo.UserName = parametros[0];
UriTo.Host = parametros[1];
UriTo.Port = int.Parse(parametros[2]);
//Envio de respuesta Ringing para situar al usuario inicial en un estado de procedimiento
SipResponse RingingResponse = new
SipResponse(InviteTrans.OriginalRequest, SipStatusCode.Ringing);
System.Net.IPAddress RemoteAddress = System.Net.IPAddress.Parse(IP); DestinationTuple destination = new DestinationTuple(new IPEndPoint(RemoteAddress, int.Parse(Puerto)), TransportProtocol.Udp);
CoreServerT.SendResponseDirect(RingingResponse, destination); InviteRequest Invite = new InviteRequest(UriTo.SipUri);
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);
Invite.AddHeader(FieldVia);
Invite.MaxForwards = trans.OriginalRequest.MaxForwards; Invite.From = InviteTrans.OriginalRequest.From;
Invite.From.RecreateTag();
Invite.To = new ToHeaderField(UriTo.SipUri);
Invite.ContactHeaders.Add(trans.OriginalRequest.ContactHeaders[0]); CallIdHeaderField callID = new CallIdHeaderField();
92
Invite.CallId = callID;
CSeqHeaderField Cseq = new CSeqHeaderField(SipMethod.Invite); Cseq.NextSequence();
Invite.CSeq = Cseq;
UserAgentHeaderField UserAg = new UserAgentHeaderField("ESIME Proxy PBX v1.0");
Invite.Date = new DateHeaderField(DateTime.Now);
for (int c = 0; c < trans.OriginalRequest.AllowHeaders.Count; c++) {
Invite.AllowHeaders.Add(trans.OriginalRequest.AllowHeaders[c]); }
for (int c = 0; c < trans.OriginalRequest.SupportedHeaders.Count; c++) {
Invite.SupportedHeaders.Add(trans.OriginalRequest.SupportedHeaders[c]); }
Invite.ContentType = trans.OriginalRequest.ContentType; Invite.Body = trans.OriginalRequest.Body;
listaCallID.Insertar(callIDpar, username, usernameDestino); System.Net.IPAddress RemoteAddressInvite =
System.Net.IPAddress.Parse(parametros[1].ToString());
DestinationTuple destinationInvite = new DestinationTuple(new
IPEndPoint(RemoteAddressInvite, int.Parse(parametros[2])), TransportProtocol.Udp); Invite.ResponseReceived += new EventHandler<ResponseReceivedEventArgs>(invite_ResponseReceived); CoreClientT.SendRequestDirect(Invite, destinationInvite); } else {
SipResponse AnywhereResponse = new
SipResponse(InviteTrans.OriginalRequest, SipStatusCode.DoesNotExistAnywhere); System.Net.IPAddress RemoteAddressAnywhereResponse =
System.Net.IPAddress.Parse(IP);
Append("ESTADO: FALLIDO");
Append("USUARIO NO ENCONTRADO");
DestinationTuple destinationAnywhereResponse = new DestinationTuple(new IPEndPoint(RemoteAddressAnywhereResponse, int.Parse(Puerto)), TransportProtocol.Udp); CoreServerT.SendResponseDirect(AnywhereResponse, destinationAnywhereResponse); } } if (trans.OriginalRequest.Method == SipMethod.Bye) {
//Response ByeResponse = Servidor.SendResponseOK(e.Request); //Servidor.Bye(ByeResponse);
} }
93
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];
94
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);
95
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];
SipResponse RespOptionsServerT = e.Response; Append(e.Response.ViaHeaders.ToString()); RespOptionsServerT.RemoveHeader("Via");
RespOptionsServerT.ViaHeaders.Add(CampoViaOptions);
System.Net.IPAddress RemoteAddress = System.Net.IPAddress.Parse("1.1.1.10"); DestinationTuple destination = new DestinationTuple(new
IPEndPoint(RemoteAddress, 5060), TransportProtocol.Udp);
CoreServerT.SendResponseDirect(RespOptionsServerT, destination); listaServidor.Eliminar(username);
}
private void SubscribeRequest_ResponseReceived(object sender, ResponseReceivedEventArgs e)
{
int port;
if (e.Response.StatusClass == SipStatusClass.Successful) {
Append("ESTADO: SUBSCRIBE 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);
96
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);
CoreServerTNotify = null;
CoreServerTNotify = new SipCore(); CoreServerTNotify.StartListening(new
IPEndPoint(System.Net.IPAddress.Parse("1.1.1.1"), port), TransportProtocol.Udp); CoreServerTNotify.ServerTransactionCreated += new EventHandler<TransactionEventArgs>(CoreServerTNotify_NewPort); } 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); } }
private void CoreServerTNotify_NewPort(object sender, TransactionEventArgs e) {
97
if (e.Transaction.OriginalRequest.Method == SipMethod.Notify) {
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.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 = { '"', '"', ':', '@' };
98
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];
SipResponse RespNotifyServerT = e.Response; RespNotifyServerT.RemoveHeader("Via");
RespNotifyServerT.ViaHeaders.Add(CampoViaNotify);
System.Net.IPAddress RemoteAddress = System.Net.IPAddress.Parse("1.1.1.10"); DestinationTuple destination = new DestinationTuple(new
IPEndPoint(RemoteAddress, 5060), TransportProtocol.Udp);
CoreServerT.SendResponseDirect(RespNotifyServerT, destination); listaServidor.Eliminar(username);
}
private void invite_ResponseReceived(object sender, ResponseReceivedEventArgs e) { if (e.Response.StatusCodeNumber == 401) { Append("===INVITE 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); } else { Append("LLAMADA EN PROCESO: "); Append("ESTADO: "+ e.Response.StatusLine.ToString()); Append(e.Response.ToString()); string dname; string username; char[] tok2 = { '"', '"', ':', '@' };
99
string from = e.Response.From.ToString(); string[] part2 = from.Split(tok2);
dname = part2[2]; username = part2[4]; string rport;
char[] tok = { '=', ';' };
string ViaResponse = e.Response.ViaHeaders.ToString(); string[] part = ViaResponse.Split(tok);
rport = part[2];
string FromRinging = e.Response.From.Uri.ToString(); char[] tokFromRing = { ':', '@' };
string[] part4 = FromRinging.Split(tokFromRing); string usernameOrigen = part4[1];
string ToRinging = e.Response.To.Uri.ToString(); char[] tokToRing = { ':', '@' };
string[] part3 = ToRinging.Split(tokToRing); string usernameDestino = part3[1];
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); CampoViaInvite = parametros[4];
SipResponse RespInviteServerT = new SipResponse(SipStatusCode.Ringing); RespInviteServerT.ViaHeaders.Add(CampoViaInvite);
FromHeaderField FromHeader = new FromHeaderField(e.Response.From.Uri); FromHeader.DisplayName = e.Response.From.DisplayName;
FromHeader.RecreateTag();
RespInviteServerT.From = FromHeader;
ToHeaderField ToHeader = new ToHeaderField(e.Response.To.Uri); ToHeader.DisplayName = e.Response.To.DisplayName;
ToHeader.RecreateTag();
RespInviteServerT.To = ToHeader;
string CallIDres = listaCallID.Buscar(usernameOrigen, usernameDestino); RespInviteServerT.CallId = CallIDres;
CSeqHeaderField CseqRinging = new CSeqHeaderField(SipMethod.Invite); CseqRinging.NextSequence();
UserAgentHeaderField UserAgRing = new UserAgentHeaderField("ESIME Proxy PBX v1.0"); RespInviteServerT.UserAgent = UserAgRing; RespInviteServerT.AllowHeaders.Add(new AllowHeaderField(SipMethod.Invite)); RespInviteServerT.AllowHeaders.Add(new AllowHeaderField(SipMethod.Ack)); RespInviteServerT.AllowHeaders.Add(new AllowHeaderField(SipMethod.Options));
100 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);
101
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);
Confirmacion.AddHeader(FieldVia);
SipUriBuilder UriTo = new SipUriBuilder(); UriTo.UserName = parametrosTo[0];
UriTo.Host = parametrosTo[1];
UriTo.Port = int.Parse(parametrosTo[2]);
RequestLine ReqLine = new RequestLine(UriTo.SipUri, SipMethod.Ack); Confirmacion.RequestLine = ReqLine;
Confirmacion.MaxForwards = "70"; Confirmacion.From = e.Response.From; Confirmacion.To = e.Response.To; SipUri URI = e.Response.From.Uri;
ContactHeaderField contact = new ContactHeaderField(URI); Confirmacion.ContactHeaders.Add(contact);
Confirmacion.CallId = e.Response.CallId;
CSeqHeaderField CseqACK = new CSeqHeaderField(SipMethod.Ack); CseqACK.NextSequence();
Confirmacion.CSeq = CseqACK;
UserAgentHeaderField UserAg = new UserAgentHeaderField("ESIME Proxy PBX v1.0");
Confirmacion.UserAgent = UserAg;
System.Net.IPAddress RemoteAddressTo = System.Net.IPAddress.Parse(parametrosTo[1]);
DestinationTuple destinationTo = new DestinationTuple(new
IPEndPoint(RemoteAddressTo, int.Parse(parametrosTo[2])), TransportProtocol.Udp); CoreClientT.SendRequestDirect(Confirmacion, destinationTo);
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];
102
RespInviteServerT.ViaHeaders.Add(CampoViaInvite);
FromHeaderField FromHeader = new FromHeaderField(e.Response.From.Uri); FromHeader.DisplayName = e.Response.From.DisplayName;
FromHeader.RecreateTag();
RespInviteServerT.From = FromHeader;
ToHeaderField ToHeader = new ToHeaderField(e.Response.To.Uri); ToHeader.DisplayName = e.Response.To.DisplayName;
ToHeader.RecreateTag();
RespInviteServerT.To = ToHeader;
string CallidVuelta = listaCallID.Buscar(usernameFrom, usernameTo);//CALL ID DEVUELTO
RespInviteServerT.CallId = CallidVuelta;
CSeqHeaderField CseqOK = new CSeqHeaderField(SipMethod.Invite); CseqOK.NextSequence();
UserAgentHeaderField UserAgOK = new UserAgentHeaderField("ESIME Proxy PBX v1.0");
RespInviteServerT.UserAgent = UserAgOK;
for (int c = 0; c < e.Response.AllowHeaders.Count; c++) {
RespInviteServerT.AllowHeaders.Add(e.Response.AllowHeaders[c]); }
for (int c = 0; c < e.Response.SupportedHeaders.Count; c++) {
RespInviteServerT.SupportedHeaders.Add(e.Response.SupportedHeaders[c]); }
SipUri URIOK = e.Response.To.Uri;
ContactHeaderField contactOK = new ContactHeaderField(URIOK); RespInviteServerT.ContactHeaders.Add(contactOK); RespInviteServerT.ContentType = e.Response.ContentType; RespInviteServerT.Body = e.Response.Body; CoreServerT.SendResponseDirect(RespInviteServerT, destination); listaCliente.Eliminar(dnameFrom, usernameFrom); //listaCallID.Eliminar(dnameFrom, } }
public void Append(string text) {
BeginInvoke(new UpdateTextCallback(AppendText), new object[] { text }); }
private void AppendText(string text) {
mostrarTextBox2.AppendText("\r\n" + text); }
public class NodoListaSoftphone {
103
public string DisplayName; public string Username; public string DireccionIP; public string Puerto; public string Via;
public NodoListaSoftphone siguiente;
public NodoListaSoftphone(string DisplayName, string Username, string DireccionIP, string Puerto, string Via)
: this(null, DisplayName, Username, DireccionIP, Puerto, Via, null) { } public NodoListaSoftphone(NodoListaSoftphone anterior, string DisplayName, string Username, string DireccionIP, string Puerto, string Via, NodoListaSoftphone siguiente) { this.anterior = anterior; this.DisplayName = DisplayName; this.Username = Username; this.DireccionIP = DireccionIP; this.Puerto = Puerto; this.Via = Via; this.siguiente = siguiente; }
public NodoListaSoftphone ANTERIOR {
get { return anterior; }
set { anterior = value; } }
public string DISPLAYNAME {
get { return DisplayName; } set { DisplayName = value; } }
public string USERNAME {
get { return Username; } set { Username = value; } }
public string DIRECCIONIP {
get { return DireccionIP; } set { DireccionIP = value; } }
public string PUERTO {
get { return Puerto; } set { Puerto = value; } }
public string VIA {
104
get { return Via; } set { Via = value; }