public void Start() { _lastupdate = DateTime.Now; _db = new SQLiteDatabase("|DataDirectory|app_data.sqlite;Version=3;"); TransportInfo localTransport = CreateTransport(Helpers.GetLocalIP(), 7202); _app = new SIPApp(localTransport); _app.RequestRecvEvent += AppRequestRecvEvent; _app.ResponseRecvEvent += AppResponseRecvEvent; const string scscfIP = "scscf.open-ims.test"; const int scscfPort = 6060; SIPStack stack = CreateStack(_app, scscfIP, scscfPort); stack.Uri = new SIPURI("*****@*****.**"); _localparty = new Address("<sip:[email protected]>"); StartTimer(); }
/// <summary> /// Creates a SIP request. /// </summary> /// <param name="method">The SIP method.</param> /// <param name="dest">The dest (either Address or string[]).</param> /// <param name="stateless">if set to <c>true</c> [act as a stateless proxy].</param> /// <param name="recordRoute">if set to <c>true</c> [record the SIP route].</param> /// <param name="headers">The SIP headers to use.</param> /// <param name="route">The route.</param> /// <returns>Message.</returns> public Message CreateRequest(string method, object dest, bool stateless = false, bool recordRoute = false, Dictionary<string, List<Header>> headers = null, List<Header> route = null) { if (method != Request.Method) { Debug.Assert(false, "method in createRequest must be same as original UAS for proxy"); } Message request = Request.Dup(); if (!stateless && Transaction == null) { Transaction = Transaction.CreateServer(Stack, this, Request, Stack.Transport, Stack.Tag, false); } if (dest.GetType() == typeof(Address)) { request.Uri = ((Address)dest).Uri.Dup(); } else if (dest is string[]) { string[] destArray = (string[])dest; string scheme = request.Uri.Scheme; string user = request.Uri.User; request.Uri = new SIPURI { Scheme = scheme, User = user, Host = destArray[0], Port = int.Parse(destArray[1]) }; } else { Debug.Assert(false, "Dest in Proxy Create Request is not a String or Address"); //else: request.uri = dest.dup() } if (request.First("Max-Forwards") != null) { object value = request.First("Max-Forwards").Value; int currentValue = int.Parse(value.ToString()); currentValue = currentValue - 1; request.InsertHeader(new Header(currentValue.ToString(), "Max-Forwards")); } else request.InsertHeader(new Header("70", "Max-Forwards")); if (recordRoute) { Address rr = new Address(Stack.Uri.ToString()); rr.Uri.Parameters["lr"] = null; rr.MustQuote = true; request.InsertHeader(new Header(rr.ToString(), "Record-Route")); } if (headers != null) request.Headers.Concat(headers).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); if (route != null) { route.Reverse(); foreach (Header header in route) { request.InsertHeader(header); } } Header viaHeader = Stack.CreateVia(); viaHeader.Attributes["branch"] = Transaction.createProxyBranch(request, false); request.InsertHeader(viaHeader, "insert"); return request; }
private static void RouteNewMessage(Message request, Proxy pua) { SIPURI to = request.Uri; string toID = to.User + "@" + to.Host; Address from = (Address)(request.First("From").Value); string fromID = from.Uri.User + "@" + from.Uri.Host; Address dest = new Address(to.ToString()); Message proxiedMessage = pua.CreateRequest(request.Method, dest, true, true); proxiedMessage.First("To").Value = dest; pua.SendRequest(proxiedMessage); }
/// <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"]; } } } }
private static void Main() { if (String.IsNullOrEmpty(_localIP)) { _localIP = Helpers.GetLocalIP(); } TransportInfo localTransport = CreateTransport(_localIP, LocalPort); _app = new SIPApp(localTransport); _app.RequestRecvEvent += AppRequestRecvEvent; _app.ResponseRecvEvent += AppResponseRecvEvent; const string scscfIP = "scscf.open-ims.test"; const int scscfPort = 6060; SIPStack stack = CreateStack(_app, scscfIP, scscfPort); stack.Uri = new SIPURI("*****@*****.**"); _localparty = new Address("<sip:[email protected]>"); PublishService(true, LocalPort); StartTimer(); Console.ReadKey(); }
/// <summary> /// Initializes a new instance of the <see cref="T:SIPLib.SIP.UserAgent" /> class. /// </summary> /// <param name="stack">The SIP stack associated with this UA.</param> /// <param name="request">An optional SIP request.</param> /// <param name="server">if set to <c>true</c> [act as a user agent server].</param> public UserAgent(SIPStack stack, Message request = null, bool server = false) { Stack = stack; //this.app = stack.app; Request = request; if (server) { Server = true; } else { Server = (request == null); } Transaction = null; CancelRequest = null; if ((request != null) && (request.Headers.ContainsKey("Call-ID"))) { CallID = (string) request.Headers["Call-ID"][0].Value; } else { CallID = stack.NewCallId(); } if ((request != null) && (request.Headers.ContainsKey("From"))) { RemoteParty = (Address) request.Headers["From"][0].Value; } else { RemoteParty = null; } if ((request != null) && (request.Headers.ContainsKey("To"))) { LocalParty = (Address) request.Headers["To"][0].Value; } else { LocalParty = null; } LocalTag = stack.Tag + _random.Next(0, 2147483647).ToString(); RemoteTag = stack.Tag + _random.Next(0, 2147483647).ToString(); if ((request != null) && (request.Headers.ContainsKey("Subject"))) { Subject = (string) request.Headers["Subject"][0].Value; } else { Subject = ""; } MaxForwards = 70; RouteSet = new List<Header>(); LocalTarget = null; RemoteTarget = null; RemoteCandidates = null; LocalSeq = 0; RemoteSeq = 0; Contact = new Address(stack.Uri.ToString()); if (LocalParty != null) { if (LocalParty.Uri.User.Length > 0) { Contact.Uri.User = LocalParty.Uri.User; } } Autoack = true; Auth = new Dictionary<string, string>(); }
/// <summary> /// Sends a SIP response. /// </summary> /// <param name="response">The SIP response (either a response code or SIP message).</param> /// <param name="responseText">Optional response text.</param> /// <param name="content">Optional content.</param> /// <param name="contentType">Optional type of the SIP body contents.</param> /// <param name="createDialog">if set to <c>true</c> [can create dialog].</param> public virtual void SendResponse(object response, string responseText = "", string content = "", string contentType = "", bool createDialog = true) { Message responseMessage; if (Request == null) { Debug.Assert(false, String.Format("Invalid request in sending a response")); return; } if (response is int) { responseMessage = CreateResponse((int) (response), responseText, content, contentType); } else { responseMessage = (Message) (response); } if (createDialog && CanCreateDialog(Request, responseMessage)) { if (Request.Headers.ContainsKey("Record-Route")) { responseMessage.Headers.Add("Record-Route", Request.Headers["Record-Route"]); } if (!responseMessage.Headers.ContainsKey("Contact")) { Address contact = new Address(Contact.ToString()); if (contact.Uri.User.Length != 0) { contact.Uri.User = ((Address) Request.First("To").Value).Uri.User; responseMessage.InsertHeader(new Header(contact.ToString(), "Contact")); } } Dialog dialog = Dialog.CreateServer(Stack, Request, responseMessage, Transaction); Stack.DialogCreated(dialog, this); Stack.Sending(dialog, responseMessage); } else { Stack.Sending(this, responseMessage); } if (Transaction == null) { Stack.Send(responseMessage, responseMessage.Headers["Via"][0].ViaUri.HostPort()); } else { Transaction.SendResponse(responseMessage); } }
/// <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> /// 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; }
private static Address RouteService(Message request, Block Block, string toId, string fromId) { string callID = request.First("Call-ID").ToString(); if (_activeFlows.ContainsKey(callID)) { ActiveFlow af = _activeFlows[callID]; af.LastRequest = request; af.LastBlock = Block; } else { ActiveFlow af = new ActiveFlow(); af.OriginalRequest = request; af.LastRequest = request; af.LastBlock = Block; _activeFlows.Add(callID,af); } Address dest = new Address(Block.DestURI); return dest; }
private static void RouteNewMessage(Message request, Proxy pua) { SIPURI to = request.Uri; string toID = to.User + "@" + to.Host; Address from = (Address)(request.First("From").Value); string fromID = from.Uri.User + "@" + from.Uri.Host; List<ServiceFlow> toUserFlows = GetUserBlocks(toID); List<ServiceFlow> fromUserFlows = GetUserBlocks(fromID); Address dest = new Address(to.ToString()); foreach (ServiceFlow serviceFlow in toUserFlows) { if (serviceFlow.Blocks.Count > 0) { Block firstBlock = serviceFlow.Blocks[serviceFlow.FirstBlockGUID]; Address temp_dest = CheckServiceBlock(request, firstBlock, toID, fromID); if (temp_dest != null) { dest = temp_dest; break; } } else continue; } Message proxiedMessage = pua.CreateRequest(request.Method, dest, true, true); proxiedMessage.First("To").Value = dest; string callID = proxiedMessage.First("Call-ID").ToString(); ActiveFlow af = new ActiveFlow (); af.LastRequest = proxiedMessage; _activeFlows[callID] = af; pua.SendRequest(proxiedMessage); }
private static void ContinueRoutingMessage(Message request, Proxy pua, Block block) { SIPURI to = request.Uri; string toID = to.User + "@" + to.Host; Address from = (Address)(request.First("From").Value); string fromID = from.Uri.User + "@" + from.Uri.Host; Address dest = new Address(to.ToString()); Address temp_dest = CheckServiceBlock(request, block, toID, fromID); if (temp_dest != null) { dest = temp_dest; } if (dest.ToString().Contains("anonymous.invalid")) { Message proxiedMessage = pua.CreateResponse(403, "Forbidden"); pua.SendResponse(proxiedMessage); } else { Message proxiedMessage = pua.CreateRequest(request.Method, dest, true, true); proxiedMessage.First("To").Value = dest; pua.SendRequest(proxiedMessage); } }