This class is used to represent a SIPURI (“Firstname Lastname” <sip:[email protected]> etc)
예제 #1
0
 //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));
         //}
     }
 }
예제 #2
0
        /// <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);
            }
        }
예제 #3
0
 /// <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);
예제 #4
0
 /// <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);
 }
예제 #5
0
        /// <summary>
        /// Creates a SIP request.
        /// </summary>
        /// <param name="method">The SIP method (invite etc.)</param>
        /// <param name="content">The SIP body contents.</param>
        /// <param name="contentType">The type of the SIP body.</param>
        /// <returns>Message.</returns>
        public virtual Message CreateRequest(string method, string content = "", string contentType = "")
        {
            Server = false;
            if (RemoteParty == null)
            {
                Debug.Assert(false, String.Format("No remoteParty for UAC\n"));
            }
            if (LocalParty == null)
            {
                LocalParty = new Address("\"Anonymous\" <sip:[email protected]>");
            }
            //TODO: Use Remote Party instead of Remote Target?
            SIPURI uri;
            if (RemoteTarget != null)
            {
                uri = new SIPURI(RemoteTarget.ToString());
            }
            else
            {
                uri = new SIPURI(RemoteParty.ToString());
            }

            if (method == "REGISTER")
            {
                //TODO: Is this right ?
                //uri.User = "";
            }
            if ((method != "ACK") && (method != "CANCEL"))
            {
                LocalSeq = ++LocalSeq;
            }
            //TODO: Use Remote Party instead of Remote Target?
            Header to;
            if (RemoteTarget != null)
            {
                to = new Header(RemoteTarget.ToString(), "To");
            }
            else
            {
                to = new Header(RemoteParty.ToString(), "To");
            }

            Header from = new Header(LocalParty.ToString(), "From");
            from.Attributes["tag"] = LocalTag;
            Header cSeq = new Header(LocalSeq + " " + method, "CSeq");
            Header callId = new Header(CallID, "Call-ID");
            Header maxForwards = new Header(MaxForwards.ToString(), "Max-Forwards");
            Header via = Stack.CreateVia();
            Dictionary<string, object> branchParams = new Dictionary<string, object>
                {
                    {"To", to.Value},
                    {"From", @from.Value},
                    {"CallId", callId.Value},
                    {"CSeq", cSeq.Number}
                };
            via.Attributes["branch"] = Transaction.CreateBranch(branchParams, false);
            if (LocalTarget == null)
            {
                LocalTarget = Stack.Uri.Dup();
                LocalTarget.User = LocalParty.Uri.User;
            }
            Header contact = new Header(LocalTarget.ToString(), "Contact");
            Header[] headerList = {to, from, cSeq, callId, maxForwards, via, contact};
            List<Header> headers = headerList.ToList();
            // Check this TODO
            //
            if (RouteSet.Count != 0)
            {
                headers.AddRange(RouteSet);
            }

            //app adds other headers such as Supported, Require and Proxy-Require
            if (!string.IsNullOrEmpty(contentType))
            {
                headers.Add(new Header(contentType, "Content-Type"));
            }
            Dictionary<string, List<Header>> headerDict = new Dictionary<string, List<Header>>();
            foreach (Header h in headers)
            {
                if (headerDict.ContainsKey(h.Name))
                {
                    headerDict[h.Name].Add(h);
                }
                else
                {
                    List<Header> temp = new List<Header> {h};
                    headerDict.Add(h.Name, temp);
                }
            }
            Request = Message.CreateRequest(method, uri, headerDict, content);
            return Request;
        }
예제 #6
0
 /// <summary>
 /// Parses the specified string into an header object.
 /// </summary>
 /// <param name="name">The header name.</param>
 /// <param name="value">The header value.</param>
 public void Parse(string name, string value)
 {
     string rest = "";
     int index = 0;
     if (Address.Contains(name.ToLower()))
     {
         HeaderType = "address";
         Address addr = new Address {MustQuote = true};
         int count = addr.Parse(value);
         Value = addr;
         if (count < value.Length)
             rest = value.Substring(count, value.Length - count);
         if (rest.Length > 0)
         {
             foreach (string parm in rest.Split(';'))
             {
                 if (parm.Contains('='))
                 {
                     index = parm.IndexOf('=');
                     string parmName = parm.Substring(0, index);
                     string parmValue = parm.Substring(index + 1);
                     Attributes.Add(parmName, parmValue);
                 }
             }
         }
     }
     else if (!(Comma.Contains(name.ToLower())) && !(Unstructured.Contains(name.ToLower())))
     {
         HeaderType = "standard";
         if (!value.Contains(";lr>"))
         {
             if (value.Contains(';'))
             {
                 index = value.IndexOf(';');
                 Value = value.Substring(0, index);
                 string tempStr = value.Substring(index + 1).Trim();
                 foreach (string parm in tempStr.Split(';'))
                 {
                     if (parm.Contains('='))
                     {
                         index = parm.IndexOf('=');
                         string parmName = parm.Substring(0, index);
                         string parmValue = parm.Substring(index + 1);
                         Attributes.Add(parmName, parmValue);
                     }
                 }
             }
             else
             {
                 Value = value;
             }
         }
         else
         {
             Value = value;
         }
     }
     if (Comma.Contains(name.ToLower()))
     {
         HeaderType = "comma";
         if (value.Contains(' '))
         {
             index = value.IndexOf(' ');
             AuthMethod = value.Substring(0, index).Trim();
             Value = value.Substring(0, index).Trim();
             string values = value.Substring(index + 1);
             foreach (string parm in values.Split(','))
             {
                 if (parm.Contains('='))
                 {
                     index = parm.IndexOf('=');
                     string parmName = parm.Substring(0, index);
                     string parmValue = parm.Substring(index + 1);
                     Attributes.Add(parmName, parmValue);
                 }
             }
         }
     }
     else if (name.ToLower() == "cseq")
     {
         HeaderType = "unstructured";
         string[] parts = value.Trim().Split(' ');
         int tempNumber = -1;
         int.TryParse(parts[0], out tempNumber);
         Number = tempNumber;
         Method = parts[1];
     }
     if (Unstructured.Contains(name.ToLower()) && name.ToLower() != "cseq")
     {
         HeaderType = "unstructured";
         Value = value;
     }
     if (name.ToLower() == "via")
     {
         string[] parts = value.Split(' ');
         string proto = parts[0];
         string addr = parts[1].Split(';')[0];
         string type = proto.Split('/')[2].ToLower();
         ViaUri = new SIPURI("sip:" + addr + ";transport=" + type);
         if (ViaUri.Port == 0)
         {
             ViaUri.Port = 5060;
         }
         if (Attributes.Keys.Contains("rport"))
         {
             int tempPort = 5060;
             int.TryParse(Attributes["rport"], out tempPort);
             ViaUri.Port = tempPort;
         }
         if ((type != "tcp") && (type != "sctp") && (type != "tls"))
         {
             if (Attributes.Keys.Contains("maddr"))
             {
                 ViaUri.Host = Attributes["maddr"];
             }
             else if (Attributes.Keys.Contains("received"))
             {
                 ViaUri.Host = Attributes["received"];
             }
         }
     }
 }
예제 #7
0
        /// <summary>
        /// Parses the specified address and sets the local variables.
        /// </summary>
        /// <param name="address">The address.</param>
        /// <returns>System.Int32.</returns>
        public int Parse(string address)
        {
            if (address.StartsWith("*"))
            {
                Wildcard = true;
                return 1;
            }
            string[] regExs =
                {
                    @"^(?<name>[a-zA-Z0-9\-\._\+\~\ \t]*)<(?<uri>[^>]+)>",
                    @"^(""(?<name>[a-zA-Z0-9\-\._\+\~\ \t]+)"")[\ \t]*<(?<uri>[^>]+)>",
                    @"^[\ \t]*(?<name>)(?<uri>[^;]+)"
                };

            foreach (string expression in regExs)
            {
                Regex exp = new Regex(expression, RegexOptions.IgnoreCase);
                MatchCollection mc = exp.Matches(address);
                foreach (Match m in mc)
                {
                    DisplayName = m.Groups["name"].ToString().Trim();
                    Uri = new SIPURI(m.Groups["uri"].ToString().Trim());
                    return m.Length;
                }
            }
            return -1;
        }
예제 #8
0
 /// <summary>
 /// Determines whether the specified URI is local.
 /// </summary>
 /// <param name="uri">The URI.</param>
 /// <returns><c>true</c> if the specified URI is local; otherwise, <c>false</c>.</returns>
 public bool IsLocal(SIPURI uri)
 {
     bool host = Stack.Transport.Host.ToString() == uri.Host || uri.Host == "localhost" ||
                 uri.Host == "127.0.0.1";
     bool port = false;
     if (uri.Port <= 0)
     {
         if (Stack.Transport.Port == 5060)
         {
             port = true;
         }
     }
     port = (Stack.Transport.Port == uri.Port) || port;
     return (host && port);
 }
예제 #9
0
        /// <summary>
        /// Sends a specific SIP request.
        /// </summary>
        /// <param name="request">The request.</param>
        public virtual void SendRequest(Message request)
        {
            if ((Request == null) && (request.Method == "REGISTER"))
            {
                if ((Transaction == null) && (Transaction.State != "completed") && (Transaction.State != "terminated"))
                {
                    //TODO This doesn't make sense....
                    Debug.Assert(false, String.Format("Cannot re-REGISTER since pending registration\n"));
                }
            }
            Request = request;

            if (!request.Headers.ContainsKey("Route"))
            {
                RemoteTarget = request.Uri;
            }
            SIPURI target = RemoteTarget;

            if (request.Headers.ContainsKey("Route"))
            {
                if (request.Headers["Route"].Count > 0)
                {
                    target = ((Address)(request.Headers["Route"][0].Value)).Uri;
                    if ((target == null) || !target.Parameters.ContainsKey("lr"))
                    {
                        request.Headers["Route"].RemoveAt(0);
                        if (request.Headers["Route"].Count > 0)
                        {
                            request.Headers["Route"].Insert(request.Headers["Route"].Count - 1,
                                                            new Header(request.Uri.ToString(), "Route"));
                        }
                        request.Uri = target;
                    }
                }
            }
            // TODO: remove any Route Header in REGISTER request
            Stack.Sending(this, request);
            if (target != null)
            {
                SIPURI dest = target.Dup();
                if (dest.Port == 0)
                {
                    dest.Port = 5060;
                }

                if (Helpers.IsIPv4(dest.Host))
                {
                    RemoteCandidates = new List <SIPURI> {
                        dest
                    };
                }
            }
            if ((RemoteCandidates == null) || (RemoteCandidates.Count == 0))
            {
                Error(null, "Cannot Resolve DNS target");
                return;
            }
            target = RemoteCandidates.First();
            RemoteCandidates.RemoveAt(0);
            if (Request.Method != "ACK")
            {
                Transaction = Transaction.CreateClient(Stack, this, Request, Stack.Transport,
                                                       target.Host + ":" + target.Port);
            }
            else
            {
                Stack.Send(Request, target.Host + ":" + target.Port);
            }
        }
예제 #10
0
        /// <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());
            }
        }
예제 #11
0
        /// <summary>
        /// Creates a SIP request.
        /// </summary>
        /// <param name="method">The SIP method (invite etc.)</param>
        /// <param name="content">The SIP body contents.</param>
        /// <param name="contentType">The type of the SIP body.</param>
        /// <returns>Message.</returns>
        public virtual Message CreateRequest(string method, string content = "", string contentType = "")
        {
            Server = false;
            if (RemoteParty == null)
            {
                Debug.Assert(false, String.Format("No remoteParty for UAC\n"));
            }
            if (LocalParty == null)
            {
                LocalParty = new Address("\"Anonymous\" <sip:[email protected]>");
            }
            //TODO: Use Remote Party instead of Remote Target?
            SIPURI uri;

            if (RemoteTarget != null)
            {
                uri = new SIPURI(RemoteTarget.ToString());
            }
            else
            {
                uri = new SIPURI(RemoteParty.ToString());
            }

            if (method == "REGISTER")
            {
                //TODO: Is this right ?
                //uri.User = "";
            }
            if ((method != "ACK") && (method != "CANCEL"))
            {
                LocalSeq = ++LocalSeq;
            }
            //TODO: Use Remote Party instead of Remote Target?
            Header to;

            if (RemoteTarget != null)
            {
                to = new Header(RemoteTarget.ToString(), "To");
            }
            else
            {
                to = new Header(RemoteParty.ToString(), "To");
            }

            Header from = new Header(LocalParty.ToString(), "From");

            from.Attributes["tag"] = LocalTag;
            Header cSeq        = new Header(LocalSeq + " " + method, "CSeq");
            Header callId      = new Header(CallID, "Call-ID");
            Header maxForwards = new Header(MaxForwards.ToString(), "Max-Forwards");
            Header via         = Stack.CreateVia();
            Dictionary <string, object> branchParams = new Dictionary <string, object>
            {
                { "To", to.Value },
                { "From", @from.Value },
                { "CallId", callId.Value },
                { "CSeq", cSeq.Number }
            };

            via.Attributes["branch"] = Transaction.CreateBranch(branchParams, false);
            if (LocalTarget == null)
            {
                LocalTarget      = Stack.Uri.Dup();
                LocalTarget.User = LocalParty.Uri.User;
            }
            Header contact = new Header(LocalTarget.ToString(), "Contact");

            Header[]      headerList = { to, from, cSeq, callId, maxForwards, via, contact };
            List <Header> headers    = headerList.ToList();

            // Check this TODO
            //
            if (RouteSet.Count != 0)
            {
                headers.AddRange(RouteSet);
            }

            //app adds other headers such as Supported, Require and Proxy-Require
            if (!string.IsNullOrEmpty(contentType))
            {
                headers.Add(new Header(contentType, "Content-Type"));
            }
            Dictionary <string, List <Header> > headerDict = new Dictionary <string, List <Header> >();

            foreach (Header h in headers)
            {
                if (headerDict.ContainsKey(h.Name))
                {
                    headerDict[h.Name].Add(h);
                }
                else
                {
                    List <Header> temp = new List <Header> {
                        h
                    };
                    headerDict.Add(h.Name, temp);
                }
            }
            Request = Message.CreateRequest(method, uri, headerDict, content);
            return(Request);
        }
예제 #12
0
        /// <summary>
        /// Parses the input string into a SIP message object.
        /// </summary>
        /// <param name="value">The value.</param>
        public void Parse(string value)
        {
            int index = 0;
            index = value.IndexOf("\r\n\r\n");
            string body = "";
            string firstheaders = "";
            if (index == -1)
            {
                firstheaders = value;
                Debug.Assert(false, String.Format("No message body, assuming empty\n{0}\n", value));
            }
            else
            {
                firstheaders = value.Substring(0, index);
                body = value.Substring(index + 1).Trim();
            }
            index = firstheaders.IndexOf("\r\n");
            string firstline = firstheaders.Substring(0, index);
            string headers = firstheaders.Substring(index + 2);
            string[] parts = firstline.Split(" ".ToCharArray(), 3);
            if (parts.Length < 3)
            {
                Debug.Assert(false, String.Format("First line has less than 3 parts \n{0}\n", firstline));
            }
            int tempResponseCode = 0;

            if (int.TryParse(parts[1], out tempResponseCode))
            {
                ResponseCode = tempResponseCode;
                ResponseText = parts[2];
                Protocol = parts[0];
                StatusCodeType = Types.GetStatusType(ResponseCode);
            }
            else
            {
                Method = parts[0];
                Uri = new SIPURI(parts[1]);
                Protocol = parts[2];
            }
            string[] stringSeparators = new[] {"\r\n"};
            foreach (string bh in headers.Split(stringSeparators, StringSplitOptions.None))
            {
                string h = bh.Trim();
                if (Regex.IsMatch(h, @"^\s"))
                {
                    break;
                }
                try
                {
                    if (!h.StartsWith("Warning:"))
                    {
                        List<Header> createdHeaders = Header.CreateHeaders(h);
                        string name = createdHeaders[0].Name;
                        if (Headers.ContainsKey(name))
                        {
                            Headers[name].AddRange(createdHeaders);
                        }
                        else
                        {
                            Headers.Add(name, createdHeaders);
                        }
                    }
                }
                catch (Exception exp)
                {
                    Debug.Assert(false, String.Format("Error parsing header {0}\n with error\n{1}", h, exp.Message));
                    break;
                }
            }
            int bodylength = 0;
            if (Headers.ContainsKey("Content-Length"))
            {
                bodylength = Convert.ToInt32(First("Content-Length").Value);
            }
            if (body.Length > 0)
            {
                Body = body;
            }
            Debug.Assert(Math.Abs(body.Length - bodylength) < 3,
                         String.Format("Invalid content-length {0} != {1}\n", body.Length, bodylength));
            string[] mandatoryHeaders = {"To", "From", "CSeq", "Call-ID"};
            foreach (string s in mandatoryHeaders)
            {
                if (!Headers.ContainsKey(s))
                {
                    Debug.Assert(false, String.Format("Mandatory header missing {0}\n", s));
                }
            }
        }
예제 #13
0
 /// <summary>
 /// Creates a SIP request message based on the passed in parameters.
 /// </summary>
 /// <param name="method">The SIP method to use.</param>
 /// <param name="uri">The destination URI used in the first line.</param>
 /// <param name="headers">The SIP headers.</param>
 /// <param name="content">The SIP body content.</param>
 /// <returns>Message.</returns>
 public static Message CreateRequest(string method, SIPURI uri, Dictionary<string, List<Header>> headers = null,
                                     string content = "")
 {
     Message m = new Message {Method = method, Uri = uri, Protocol = "SIP/2.0"};
     m = PopulateMessage(m, headers, content);
     if (m.Headers.ContainsKey("CSeq"))
     {
         Header cseq = new Header(m.First("CSeq").Number.ToString() + " " + method, "CSeq");
         List<Header> cseqHeaders = new List<Header> {cseq};
         m.Headers["CSeq"] = cseqHeaders;
     }
     return m;
 }
예제 #14
0
        /// <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;
            }
        }
예제 #15
0
 /// <summary>
 /// Initializes the necessary objects for the class.
 /// </summary>
 private void Init()
 {
     DisplayName = "";
     Uri = new SIPURI();
     Wildcard = false;
 }
예제 #16
0
 public override UserAgent CreateServer(Message request, SIPURI uri, SIPStack stack)
 {
     if (request.Method != "CANCEL")
     {
         return new Proxy(Stack, request, true);
     }
     else return null;
 }
예제 #17
0
 /// <summary>
 /// Helper function to compares this SIPURI to another specified SIPURI.
 /// </summary>
 /// <param name="other">The other.</param>
 /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
 public bool Compare(SIPURI other)
 {
     return ((ToString().ToLower()) == (other.ToString().ToLower()));
 }
예제 #18
0
 public override UserAgent CreateServer(Message request, SIPURI uri, SIPStack stack)
 {
     if (request.Method == "INVITE")
     {
         return new UserAgent(Stack, request);
     }
     return null;
 }
예제 #19
0
 /// <summary>
 /// Creates a SIP register request.
 /// </summary>
 /// <param name="aor">The address-of-record.</param>
 /// <returns>Message.</returns>
 public virtual Message CreateRegister(SIPURI aor)
 {
     if (aor != null)
     {
         RemoteParty = new Address(aor.ToString());
     }
     if (LocalParty == null)
     {
         LocalParty = new Address(RemoteParty.ToString());
     }
     Message m = CreateRequest("REGISTER");
     m.InsertHeader(new Header("", "Authorization"));
     return m;
 }