//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)); //} } }
/// <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> /// 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> /// 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> /// 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; }
/// <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"]; } } } }
/// <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; }
/// <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); }
/// <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); } }
/// <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()); } }
/// <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); }
/// <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)); } } }
/// <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; }
/// <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> /// Initializes the necessary objects for the class. /// </summary> private void Init() { DisplayName = ""; Uri = new SIPURI(); Wildcard = false; }
public override UserAgent CreateServer(Message request, SIPURI uri, SIPStack stack) { if (request.Method != "CANCEL") { return new Proxy(Stack, request, true); } else return null; }
/// <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())); }
public override UserAgent CreateServer(Message request, SIPURI uri, SIPStack stack) { if (request.Method == "INVITE") { return new UserAgent(Stack, request); } return null; }
/// <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; }