/// <summary> /// Triggered on receipt of any responses. Updates state of transaction. /// </summary> /// <param name="response">The SIP response message.</param> public override void ReceivedResponse(Message response) { if (response.Is1XX()) { if (State == "trying") { State = "proceeding"; App.ReceivedResponse(this, response); } else if (State == "proceeding") { App.ReceivedResponse(this, response); } } else if (response.IsFinal()) { if (State == "trying" || State == "proceeding") { State = "completed"; App.ReceivedResponse(this, response); if (!Transport.Reliable) { StartTimer("K", Timer.K()); } else { Timeout("K", 0); } } } }
/// <summary> /// Receives the SIP response /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="response">The response.</param> public override void ReceivedResponse(Transaction transaction, Message response) { ProxyBranch branch = GetBranch(transaction); if (branch == null) { Debug.Assert(false, "Invalid transaction received " + transaction); return; } if (response.Is1XX() && branch.CancelRequest != null) { Transaction cancel = Transaction.CreateClient(Stack, this, branch.CancelRequest, transaction.Transport, transaction.Remote); branch.CancelRequest = null; } else { if (response.IsFinal()) { branch.Response = response; Stack.ReceivedResponse(this, response); //SendResponseIfPossible(); } else { response.Headers["Via"].RemoveAt(0); if (response.Headers["Via"].Count <= 0) { response.Headers.Remove("Via"); } SendResponse(response); Stack.ReceivedResponse(this, response); } } }
/// <summary> /// Sends a response based on this transaction. /// </summary> /// <param name="response">The response.</param> public override void SendResponse(Message response) { LastResponse = response; if (response.Is1XX()) { if (State == "proceeding") { Stack.Send(response, Remote, Transport); } } else if (response.Is2XX()) { if (State == "proceeding") { State = "terminated"; Stack.Send(response, Remote, Transport); } } else { if (State == "proceeding") { State = "completed"; if (!Transport.Reliable) { StartTimer("G", Timer.G()); } StartTimer("H", Timer.H()); Stack.Send(response, Remote, Transport); } } }
/// <summary> /// Triggered on receipt of any responses. Updates state of transaction. /// </summary> /// <param name="response">The response.</param> public override void ReceivedResponse(Message response) { if (response.Is1XX()) { if (State == "calling") { State = "proceeding"; App.ReceivedResponse(this, response); } else if (State == "proceeding") { App.ReceivedResponse(this, response); } } else if (response.Is2XX()) { if (State == "calling" || State == "proceeding") { State = "terminated"; App.ReceivedResponse(this, response); } } else { if (State == "calling" || State == "proceeding") { State = "completed"; Stack.Send(CreateAck(response), Remote, Transport); App.ReceivedResponse(this, response); if (!Transport.Reliable) { StartTimer("D", Timer.D()); } else { Timeout("D", 0); } } else if (State == "completed") { Stack.Send(CreateAck(response), Remote, Transport); } } }
/// <summary> /// Triggered on receipt of a SIP response. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="response">The response.</param> public override void ReceivedResponse(Transaction transaction, Message response) { if (response.Is2XX() && response.Headers.ContainsKey("Contact") && transaction != null && transaction.Request.Method == "INVITE") { RemoteTarget = new SIPURI(((Address)(Request.First("Contact").Value)).Uri.ToString()); } if (!response.Is1XX()) { Clients.RemoveAll(x => x == transaction); } if (response.ResponseCode == 408 || response.ResponseCode == 481) { Close(); } if (response.ResponseCode == 401 || response.ResponseCode == 407) { if (Authenticate(response, transaction)) { Stack.ReceivedResponse(this, response); } } else if (transaction != null) { Stack.ReceivedResponse(this, response); } if (Autoack && response.Is2XX() && (transaction != null && transaction.Request.Method == "INVITE" || response.First("CSeq").Method == "INVITE")) { Message ack = CreateRequest("ACK"); SendRequest(ack); } }
/// <summary> /// Virtual function for receiving a response. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="response">The response.</param> public virtual void ReceivedResponse(Transaction transaction, Message response) { if ((transaction != null) && transaction != Transaction) { Debug.Assert(false, String.Format("Invalid transaction received {0} != {1}", transaction, Transaction)); return; } if (response.Headers["Via"].Count > 1) { Debug.Assert(false, String.Format("More than one Via header in resposne")); return; } if (response.Is1XX()) { if (CancelRequest != null) { Transaction cancel = Transaction.CreateClient(Stack, this, CancelRequest, transaction.Transport, transaction.Remote); CancelRequest = null; } else { Stack.ReceivedResponse(this, response); } } else if ((response.ResponseCode == 401) || (response.ResponseCode == 407)) { if (!Authenticate(response, Transaction)) { Stack.ReceivedResponse(this, response); } } else { if (CanCreateDialog(Request, response)) { Dialog dialog = Dialog.CreateClient(Stack, Request, response, transaction); dialog.App = this; Stack.DialogCreated(dialog, this); Stack.ReceivedResponse(dialog, response); if ((Autoack) && (Request.Method == "INVITE")) { Message ack = dialog.CreateRequest("ACK"); // TODO: Check dialog RouteSet creation (the manual hack below works) //if (response.Headers.ContainsKey("Record-Route")) //{ // ack.Headers["Route"] = response.Headers["Record-Route"]; // ack.Headers["Route"].Reverse(); //foreach (Header h in Headers["Route"]) //{ // h.Name = "Route"; //} //} dialog.SendRequest(ack); } } else { Stack.ReceivedResponse(this, response); } } }