/// <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> /// Triggered on receipt of any requests. Updates state of transaction /// </summary> /// <param name="receivedRequest">The received request.</param> public override void ReceivedRequest(Message receivedRequest) { if (Request.Method == receivedRequest.Method) { if (State == "proceeding" || State == "completed") { if (LastResponse != null) { Stack.Send(LastResponse, Remote, Transport); } } } else if (receivedRequest.Method == "ACK") { if (State == "completed") { State = "confirmed"; if (!Transport.Reliable) { StartTimer("I", Timer.I()); } else { Timeout("I", 0); } } else if (State == "confirmed") { //Ignore duplicate ACK } } }
public void ProcessMessage(Message request) { if (request.First("Content-Type").ToString().ToUpper().Contains("TEXT/PLAIN")) { try { if (MessageRecievedEvent != null) { MessageRecievedEvent(this, new MessageReceivedArgs(request.First("From").Value.ToString(), request.Body)); } } catch (Exception exception) { MessageBox.Show("Error in handling IM Message : " + exception.Message); } } else if (request.First("Content-Type").ToString().ToUpper().Equals("APPLICATION/IM-ISCOMPOSING+XML")) { try { if (TypingMessageRecievedEvent != null) { TypingMessageRecievedEvent(this, new TypingMessageRecievedArgs(request.First("From").Value.ToString(), request.Body)); } } catch (Exception exception) { MessageBox.Show("Error in handling IM Message : " + exception.Message); } } }
/// <summary> /// Initializes a new instance of the <see cref="T:SIPLib.SIP.ProxyBranch"/> class. /// </summary> public ProxyBranch() { Request = null; Response = null; RemoteCandidates = null; Transaction = null; CancelRequest = null; }
public void ProcessRequest(Message request) { if (request.Method.ToUpper().Contains("NOTIFY")) { if (request.Headers.ContainsKey("Content-Length")) { if (request.Body.Length > 0) { try { XDocument xDoc = XDocument.Parse(request.Body.Trim()); string basic = ""; string note = ""; foreach (XElement xElement in xDoc.Descendants()) { switch (xElement.Name.ToString()) { case "{urn:ietf:params:xml:ns:pidf}basic": basic = xElement.Value; break; case "{urn:ietf:params:xml:ns:pidf}note": note = xElement.Value; break; } } if (PresenceChangedEvent != null) { string contact = request.First("From").Value.ToString(); contact = contact.Replace("<",""); contact = contact.Replace(">",""); PresenceChangedEvent(this, new PresenceChangedArgs(contact, basic, note)); } } catch (Exception exception) { MessageBox.Show("Error in handling presence xml: " + exception.Message); } } } } }
internal void AcceptCall(SDP sdp, Message IncomingCall) { foreach (UserAgent userAgent in Useragents.ToArray()) { if (userAgent.CallID == IncomingCall.First("Call-ID").Value.ToString()) { Message response = userAgent.CreateResponse(200, "OK"); response.InsertHeader(new Header("application/sdp", "Content-Type")); response.Body = sdp.ToString(); userAgent.SendResponse(response); } } }
public override void ReceivedResponse(UserAgent ua, Message response, SIPStack stack) { Log.Info("Received response with code " + response.ResponseCode + " " + response.ResponseText); Log.Debug("\n\n" + response.ToString()); if (ResponseRecvEvent != null) { ResponseRecvEvent(this, new SipMessageEventArgs(response)); } }
public override UserAgent CreateServer(Message request, SIPURI uri, SIPStack stack) { if (request.Method == "INVITE") { return new UserAgent(Stack, request); } return null; }
/// <summary> /// Sends the SIP request. /// </summary> /// <param name="request">The request.</param> public override void SendRequest(Message request) { SIPURI target = null; if (request.First("Route") == null) { target = request.Uri; } else { var routes = request.Headers["Route"]; if (routes.Count > 0) { try { target = ((Address)routes[0].Value).Uri; string test = target.Parameters["lr"]; } catch (Exception) { routes.RemoveAt(0); if (routes.Count > 0) { routes.Add(new Header(request.Uri.ToString(), "Route")); } request.Headers["Route"] = routes; request.Uri = target; } } } Stack.Sending(this, request); ProxyBranch branch = new ProxyBranch(); SIPURI dest = target.Dup(); if (target.Port <= 0) { dest.Port = 5060; } else { dest.Port = target.Port; } if (!Helpers.IsIPv4(dest.Host)) { try { IPAddress[] addresses = Dns.GetHostAddresses(dest.Host); dest.Host = addresses[0].ToString(); } catch (Exception) { } } if (Helpers.IsIPv4(dest.Host)) { branch.RemoteCandidates = new List<SIPURI> { dest }; } if (branch.RemoteCandidates == null || branch.RemoteCandidates.Count == 0) { Error(null, "Cannot resolve DNS target"); return; } target = branch.RemoteCandidates.First(); branch.RemoteCandidates.RemoveAt(0); if (!request.Method.ToUpper().Contains("ACK")) { branch.Transaction = Transaction.CreateClient(Stack, this, request, Stack.Transport, target.HostPort()); branch.Request = request; _branches.Add(branch); } else { Stack.Send(request, target.HostPort()); } }
public override void ReceivedRequest(Transaction transaction, Message request) { //try //{ if ((transaction != null) && Transaction != null && Transaction != transaction && request.Method.ToUpper() != "CANCEL") { Debug.Assert(false, "Invalid transaction for received request"); } Server = true; if (!request.Uri.Scheme.ToLower().Equals("sip")) { SendResponse(416, "Unsupported URI scheme"); return; } if (request.First("Max-Forwards") != null && int.Parse(request.First("Max-Forwards").Value.ToString()) < 0) { SendResponse(483, "Too many hops"); return; } if (!request.Headers["To"][0].Attributes.ContainsKey("tag") && transaction != null) { if (Stack.FindOtherTransactions(request, transaction) != null) { //SendResponse(482, "Loop detected - found another transaction"); return; } } if (request.First("Proxy-Require") != null) { if (!request.Method.ToUpper().Contains("CANCEL") && !request.Method.ToUpper().Contains("ACK")) { Message response = CreateResponse(420, "Bad extension"); Header unsupported = request.First("Proxy-Require"); unsupported.Name = "Unsupported"; response.InsertHeader(unsupported); SendResponse(unsupported); return; } } if (transaction != null) { Transaction = transaction; } if (request.Method.ToUpper() == "CANCEL") { string branch; if (request.First("Via") != null && request.First("Via").Attributes.ContainsKey("branch")) { branch = request.First("Via").Attributes["branch"]; } else { branch = Transaction.CreateBranch(request, true); } Transaction original = Stack.FindTransaction(Transaction.CreateId(branch, "INVITE")); if (original != null) { if (original.State == "proceeding" || original.State == "trying") { original.SendResponse(original.CreateResponse(487, "Request terminated")); } transaction = Transaction.CreateServer(Stack, this, request, Stack.Transport, Stack.Tag, false); transaction.SendResponse(transaction.CreateResponse(200, "OK")); } SendCancel(); return; } if (string.IsNullOrEmpty(request.Uri.User) && IsLocal(request.Uri) && request.Uri.Parameters != null && request.First("Route") != null) { Header lastRoute = request.Headers["Route"].Last(); request.Headers["Route"].RemoveAt(request.Headers["Route"].Count - 1); request.Uri = ((Address)(lastRoute.Value)).Uri; } if (request.First("Route") != null && IsLocal(((Address)(request.First("Route").Value)).Uri)) { request.Headers["Route"].RemoveAt(0); request.had_lr = true; } Stack.ReceivedRequest(this, request); //} //catch (Exception) //{ // throw; //} }
public override UserAgent CreateServer(Message request, SIPURI uri, SIPStack stack) { if (request.Method != "CANCEL") { return new Proxy(Stack, request, true); } else return null; }
/// <summary> /// Stub to create a SIP server user agent. /// </summary> /// <param name="request">The request.</param> /// <param name="uri">The URI.</param> /// <param name="sipStack">The sip stack.</param> /// <returns>UserAgent.</returns> public abstract UserAgent CreateServer(Message request, SIPURI uri, SIPStack sipStack);
/// <summary> /// Stub to alert on cancellation. /// </summary> /// <param name="ua">The ua.</param> /// <param name="request">The request.</param> /// <param name="sipStack">The sip stack.</param> public abstract void Cancelled(UserAgent ua, Message request, SIPStack sipStack);
/// <summary> /// Stub to alert on sending of a SIP message. /// </summary> /// <param name="ua">The ua.</param> /// <param name="message">The message.</param> /// <param name="sipStack">The sip stack.</param> public abstract void Sending(UserAgent ua, Message message, SIPStack sipStack);
/// <summary> /// Stub to receive a response. /// </summary> /// <param name="ua">The ua.</param> /// <param name="response">The response.</param> /// <param name="sipStack">The sip stack.</param> public abstract void ReceivedResponse(UserAgent ua, Message response, SIPStack sipStack);
/// <summary> /// Handle received request /// </summary> /// <param name="m">The received message.</param> /// <param name="uri">The SIPURI that sent the message.</param> private void ReceivedRequest(Message m, SIPURI uri) { string branch = m.Headers["Via"][0].Attributes["branch"]; Transaction t; if (m.Method == "ACK") { if (branch == "0") { t = null; } else { t = FindTransaction(branch); if (t == null || (t.LastResponse != null && t.LastResponse.Is2XX())) { t = FindTransaction(Transaction.CreateId(branch, m.Method)); } } } else { t = FindTransaction(Transaction.CreateId(branch, m.Method)); } if (t == null) { UserAgent app = null; // Huh ? if ((m.Method != "CANCEL") && (m.Headers["To"][0].Attributes.ContainsKey("tag"))) { //In dialog request Dialog d = FindDialog(m); if (d == null) { if (m.Method != "ACK") { //Updated from latest code TODO UserAgent u = CreateServer(m, uri); if (u != null) { app = u; } else { // TODO: FIX NOTIFY ON SUBSCRIBE HANDLING if (m.Method != "NOTIFY") { Send(Message.CreateResponse(481, "Dialog does not exist", null, null, m)); return; } else { string branchID = m.Headers["Via"][0].Attributes["branch"]; if (_seenNotifys.ContainsKey(branchID) && _seenNotifys[branchID] > 1) { Send(Message.CreateResponse(481, "Dialog does not exist", null, null, m)); return; } else { if (_seenNotifys.ContainsKey(branchID)) { _seenNotifys[branchID] = _seenNotifys[branchID] + 1; } else { _seenNotifys[branchID] = 1; } } } return; } } else { _log.Info("No dialog for ACK, finding transaction"); if (t == null && branch != "0") { t = FindTransaction(Transaction.CreateId(branch, "INVITE")); } if (t != null && t.State != "terminated") { t.ReceivedRequest(m); return; } else { _log.Info("No existing transaction for ACK \n"); UserAgent u = CreateServer(m, uri); if (u != null) { app = u; } else return; } } } else { app = d; } } else if (m.Method != "CANCEL") { //Out of dialog request UserAgent u = CreateServer(m, uri); if (u != null) { //TODO error..... app = u; } else if (m.Method == "OPTIONS") { //Handle OPTIONS Message reply = Message.CreateResponse(200, "OK", null, null, m); reply.InsertHeader(new Header("INVITE,ACK,CANCEL,BYE,OPTION,MESSAGE,PUBLISH", "Allow")); Send(m); return; } else if (m.Method == "MESSAGE") { //Handle MESSAGE UserAgent ua = new UserAgent(this) {Request = m}; /*Message reply = ua.CreateResponse(200, "OK"); Send(reply);*/ App.ReceivedRequest(ua, m, this); return; } else if (m.Method == "PUBLISH") { UserAgent ua = new UserAgent(this) {Request = m}; App.ReceivedRequest(ua, m, this); return; } else if (m.Method != "ACK") { Send(Message.CreateResponse(405, "Method not allowed", null, null, m)); return; } } else { //Cancel Request Transaction o = FindTransaction(Transaction.CreateId(m.Headers["Via"][0].Attributes["branch"], "INVITE")); if (o == null) { Send(Message.CreateResponse(481, "Original transaction does not exist", null, null, m)); return; } app = o.App; } if (app != null) { //t = Transaction.CreateServer(app.Stack, app, app.Request, app.Stack.Transport, app.Stack.Tag); // TODO: Check app or this ? t = Transaction.CreateServer(this, app, m, Transport, Tag); } else if (m.Method != "ACK") { Send(Message.CreateResponse(404, "Not found", null, null, m)); } } else { t.ReceivedRequest(m); } }
/// <summary> /// Handles the received response and passes it to the appropriate transaction or dialog for further handling. /// </summary> /// <param name="r">The received response.</param> /// <param name="uri">The SIP URI.</param> private void ReceivedResponse(Message r, SIPURI uri) { if (r.Headers.ContainsKey("Service-Route") && r.Is2XX() && r.First("CSeq").Method.Contains("REGISTER")) { ServiceRoute = r.Headers["Service-Route"]; foreach (Header h in ServiceRoute) { h.Name = "Route"; } } else if (r.Headers.ContainsKey("Record-Route") && r.Is2XX()) { // TODO: FIX This ? don't need to keep building record-route ? //InviteRecordRoute = r.Headers["Record-Route"]; //foreach (Header h in InviteRecordRoute) //{ // h.Name = "Route"; //} } if (!r.Headers.ContainsKey("Via")) { Debug.Assert(false, String.Format("No Via header in received response \n{0}\n", r)); return; } string branch = r.Headers["Via"][0].Attributes["branch"]; string method = r.Headers["CSeq"][0].Method; Transaction t = FindTransaction(Transaction.CreateId(branch, method)); if (t == null) { if ((method == "INVITE") && (r.Is2XX())) { _log.Debug("Looking for dialog with ID " + Dialog.ExtractID(r)); foreach (KeyValuePair<string, Dialog> keyValuePair in Dialogs) { _log.Debug("Current Dialogs " + keyValuePair.Key); } Dialog d = FindDialog(r); if (d == null) { Debug.Assert(false, String.Format("No transaction or dialog for 2xx of INVITE \n{0}\n", r)); return; } else { d.ReceivedResponse(null, r); } } else { Console.WriteLine("No Transaction for response...ignoring...."); //Debug.Assert(false, String.Format("No Transaction for response \n{0}\n", r.ToString())); return; } } else { t.ReceivedResponse(r); return; } }
/// <summary> /// Passes the notification of a cancellation to the associated SIP application. /// </summary> /// <param name="ua">The ua.</param> /// <param name="request">The request.</param> public void Cancelled(UserAgent ua, Message request) { App.Cancelled(ua, request, this); }
/// <summary> /// Simply passed the request on to the receivedRequest function when acting as a proxy. /// </summary> /// <param name="request">The request.</param> /// <returns>Transaction.</returns> public Transaction CreateTransaction(Message request) { ReceivedRequest(null, request); return null; }
/// <summary> /// Creates the SIP server. /// </summary> /// <param name="request">The request.</param> /// <param name="uri">The URI.</param> /// <returns>UserAgent.</returns> public UserAgent CreateServer(Message request, SIPURI uri) { return App.CreateServer(request, uri, this); }
/// <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> /// Finds any other transactions. /// </summary> /// <param name="r">The SIP message.</param> /// <param name="orig">The original transaction.</param> /// <returns>Another matching transaction.</returns> public Transaction FindOtherTransactions(Message r, Transaction orig) { foreach (Transaction t in Transactions.Values) { if ((t != orig) && (Transaction.TEquals(t, r, orig))) return t; } return null; }
/// <summary> /// Initializes a new instance of the <see cref="T:SIPLib.SIP.Proxy"/> class. /// </summary> /// <param name="stack">The SIP stack to use.</param> /// <param name="request">The incoming request to proxy.</param> /// <param name="server">if set to <c>true</c> [server].</param> public Proxy(SIPStack stack, Message request, bool server) : base(stack, request, server) { if (request == null) Debug.Assert(false, "Cannot create Proxy without incoming request"); }
//private string mergeRoutes(string message_text) //{ // string route = "Route: "; // StringBuilder sb = new StringBuilder(); // int index = -1; // foreach (string line in message_text.Split(new string[] { "\r\n" }, StringSplitOptions.None)) // { // if (line.StartsWith("Route:")) // { // route = route + line.Remove(0, 6) + ","; // } // else if (line.StartsWith("Content-Length")) // { // route = route.Remove(route.Length - 1); // sb.Append(route + "\r\n"); // sb.Append(line + "\r\n"); // sb.Append("\r\n"); // index = message_text.IndexOf(line) + line.Length; // break; // } // else // { // sb.Append(line + "\r\n"); // } // } // sb.Append(message_text.Substring(index)); // return sb.ToString(); //} /// <summary> /// Processing of raw received data /// </summary> /// <param name="data">The received data.</param> /// <param name="src">The data source.</param> public void Received(string data, string[] src) { // Ignore empty messages sent by the openIMS core. if (data.Length > 2) { if (data.Contains("INVITE")) { //Hook to log particular types of messages _log.Debug(new Message(data)); } //try //{ Message m = new Message(data); SIPURI uri = new SIPURI("sip" + ":" + src[0] + ":" + src[1]); if (m.Method != null) { if (!m.Headers.ContainsKey("Via")) { Debug.Assert(false, String.Format("No Via header in request \n{0}\n", m)); } Header via = m.Headers["Via"].First(); if (via.ViaUri.Host != src[0] || !src[1].Equals(via.ViaUri.Port)) { via.Attributes.Add("received", src[0]); via.ViaUri.Host = src[0]; } if (via.Attributes.ContainsKey("rport")) { via.Attributes["rport"] = src[1]; } via.ViaUri.Port = Convert.ToInt32(src[1]); ReceivedRequest(m, uri); } else if (m.ResponseCode > 0) { ReceivedResponse(m, uri); } else { Debug.Assert(false, String.Format("Received invalid message \n{0}\n", m)); } //} //catch (Exception ex) //{ // Debug.Assert(false, // String.Format("Error in received message \n{0}\n with error message {1}", data, // ex.Message)); //} } }
public override void ReceivedRequest(UserAgent ua, Message request, SIPStack stack) { Log.Info("Received request with method " + request.Method.ToUpper()); Log.Debug("\n\n" + request.ToString()); if (RequestRecvEvent != null) { RequestRecvEvent(this, new SipMessageEventArgs(request, ua)); } }
/// <summary> /// Passes a received request to the associated SIP application. /// </summary> /// <param name="ua">The ua.</param> /// <param name="request">The request.</param> public void ReceivedRequest(UserAgent ua, Message request) { App.ReceivedRequest(ua, request, this); }
public override void Sending(UserAgent ua, Message message, SIPStack stack) { if (Helpers.IsRequest(message)) { Log.Info("Sending request with method " + message.Method); } else { Log.Info("Sending response with code " + message.ResponseCode); } Log.Debug("\n\n" + message.ToString()); //TODO: Allow App to modify message before it gets sent?; }
/// <summary> /// Passes a received response to the associated SIP application. /// </summary> /// <param name="ua">The ua.</param> /// <param name="response">The response.</param> public void ReceivedResponse(UserAgent ua, Message response) { App.ReceivedResponse(ua, response, this); }
public override void Cancelled(UserAgent ua, Message request, SIPStack stack) { throw new NotImplementedException(); }
/// <summary> /// Sends a particular message through the associated SIP application. /// </summary> /// <param name="ua">The ua.</param> /// <param name="message">The message.</param> public void Sending(UserAgent ua, Message message) { App.Sending(ua, message, this); }