/// <summary> /// Sends the search response message. /// </summary> protected void SendSearchResponse(SsdpMessage msg, ISsdpAnnouncer announcer) { // If we were stopped then don't bother sending this message if (!this.Server.IsListening) { return; } // Determine matching locations to respond with // If none are found then just respond with all of our locations var locations = announcer.GetLocations(addr => addr.Equals(msg.Destination.Address)).ToArray(); if (!locations.Any()) { locations = announcer.GetLocations(addr => addr.AddressFamily == msg.Source.AddressFamily).ToArray(); } foreach (var location in locations) { var response = Protocol.CreateSearchResponse(location, msg.SearchType, announcer.USN, announcer.MaxAge, Protocol.DefaultUserAgent); byte[] bytes = Encoding.ASCII.GetBytes(response); Trace.WriteLine(string.Format("Sending SearchResponse [{0}, {1}] from {2} to {3}", msg.SearchType, msg.USN, this.Server.LocalEndpoint, msg.Source), AppInfo.Application); this.Server.Send(bytes, bytes.Length, msg.Source); } }
/// <summary> /// Parses the specified reader. /// </summary> /// <param name="reader">The reader.</param> /// <param name="endPoint">The end point.</param> /// <returns></returns> public static SsdpMessage Parse(TextReader reader, IPEndPoint endPoint) { var message = new SsdpMessage(endPoint); message.FromStream(reader); return(message); }
/// <summary> /// Parses the specified reader. /// </summary> /// <param name="reader">The reader.</param> /// <param name="source">The source.</param> /// <param name="destination">The destination.</param> /// <returns></returns> public static SsdpMessage Parse(TextReader reader, IPEndPoint source, IPEndPoint destination) { var message = new SsdpMessage(true, source, destination); message.FromStream(reader); return(message); }
/// <summary> /// Called when [result found]. /// </summary> /// <param name="result">The result.</param> protected virtual void OnResultFound(SsdpMessage result) { // This is a search so ignore any advertisements we get if (result.IsAdvertisement) { return; } // If this is not a notify message then ignore it if (result.IsRequest) { return; } // Check to make sure this message matches our filter var filter = this.Filter; if (!filter(result)) { return; } var handler = this.ResultFound; if (handler != null) { handler(this, new EventArgs <SsdpMessage>(result)); } }
protected virtual void OnDeviceFound(SsdpMessage msg) { var handler = this.DeviceFound; if (handler != null) { handler(this, new EventArgs <SsdpMessage>(msg)); } }
/// <summary> /// Occurs when SSDP bye bye /// </summary> /// <param name="msg"></param> protected virtual void OnSsdpByeBye(SsdpMessage msg) { var handler = this.SsdpByeBye; if (handler != null) { handler(this, new EventArgs <SsdpMessage>(msg)); } }
/// <summary> /// Gets the matching responders. /// </summary> /// <param name="msg">The MSG.</param> /// <returns></returns> public IEnumerable <ISsdpAnnouncer> GetMatchingResponders(SsdpMessage msg) { lock (this.Announcers) { foreach (var pair in this.Announcers.Where(pair => pair.Value && pair.Key.IsMatch(msg))) { yield return(pair.Key); } } }
protected override void OnSsdpMessageReceived(SsdpMessage msg) { // Ignore any advertisements if (msg.IsAdvertisement) { return; } // Set up our dispatcher to send the response to each matching announcer that supports responding foreach (var announcer in this.GetMatchingResponders(msg)) { var temp = announcer; Dispatcher.Add(() => this.SendSearchResponse(msg, temp), TimeSpan.FromSeconds(new Random().Next(0, msg.MaxAge))); } }
/// <summary> /// Sends the search response message. /// </summary> protected void SendSearchResponse(SsdpMessage msg, SsdpAnnouncer announcer) { lock (this.Server) { // If we were stopped then don't bother sending this message if (!this.Server.IsListening) { return; } byte[] bytes = Encoding.ASCII.GetBytes(Protocol.CreateAliveResponse( announcer.Location, msg.SearchType, announcer.USN, announcer.MaxAge, Protocol.DefaultUserAgent));; this.Server.Send(bytes, bytes.Length, msg.Source); } }
/// <summary> /// Gets the matching responders. /// </summary> /// <param name="msg">The MSG.</param> /// <returns></returns> public IEnumerable<SsdpAnnouncer> GetMatchingResponders(SsdpMessage msg) { lock (this.Announcers) { foreach (var pair in this.Announcers.Where(pair => pair.Value)) { if (msg.SearchType == Protocol.SsdpAll) yield return pair.Key; if (msg.SearchType.StartsWith("uuid:") && msg.SearchType == pair.Key.USN) yield return pair.Key; if (msg.SearchType == pair.Key.NotificationType) yield return pair.Key; } } }
/// <summary> /// Sends the search response message. /// </summary> protected void SendSearchResponse(SsdpMessage msg, ISsdpAnnouncer announcer) { this.Sockets.ForEachSocket(socket => { // If we were stopped then don't bother sending this message if (!socket.IsListening) { return; } var aliveResponse = Protocol.CreateAliveResponse(socket.Location.ToString(), msg.SearchType, announcer.USN, announcer.MaxAge, Protocol.DefaultUserAgent); var bytes = Encoding.ASCII.GetBytes(aliveResponse); Trace.WriteLine(string.Format("Sending SearchResponse [{0}, {1}] from {2} to {3}", msg.SearchType, msg.USN, socket.LocalEndpoint, msg.Source), AppInfo.Application); socket.Send(bytes, bytes.Length, msg.Source); }); }
protected virtual void OnSsdpMessageReceived(SsdpMessage ssdpMessage) { var handler = this.SsdpMessageReceived; if (handler != null) { handler(this, new EventArgs <SsdpMessage>(ssdpMessage)); } if (ssdpMessage.IsAlive) { this.OnSsdpAlive(ssdpMessage); } else if (ssdpMessage.IsByeBye) { this.OnSsdpByeBye(ssdpMessage); } }
/// <summary> /// Finds the first SsdpMessage that matches our Filter. /// </summary> /// <param name="waitForTime">The wait for time.</param> /// <returns></returns> public SsdpMessage FindFirst(TimeSpan waitForTime) { object syncRoot = new object(); SsdpMessage result = null; EventHandler <EventArgs <SsdpMessage> > resultHandler = null; // Create our handler to make all the magic happen resultHandler = (sender, e) => { lock (syncRoot) { // If we already got our first result then ignore this if (result != null) { return; } // This is our first result so set our value, remove the handler, and cancel the search result = e.Value; this.SsdpMessageReceived -= resultHandler; Monitor.Pulse(syncRoot); } }; try { // Add our handler and start the async search this.SsdpMessageReceived += resultHandler; // Wait until our search is complete lock (syncRoot) { Monitor.Wait(syncRoot, waitForTime); } } finally { // Make sure we remove our handler when we're done this.SsdpMessageReceived -= resultHandler; } return(result); }
/// <summary> /// Finds the first result. /// </summary> /// <param name="destinations">The destinations.</param> /// <returns></returns> public SsdpMessage FindFirst(params IPEndPoint[] destinations) { object syncRoot = new object(); SsdpMessage result = null; EventHandler <EventArgs <SsdpMessage> > resultHandler = null; // Create our handler to make all the magic happen resultHandler = (sender, e) => { lock (syncRoot) { // If we already got our first result then ignore this if (result != null) { return; } // This is our first result so set our value, remove the handler, and cancel the search result = e.Value; this.ResultFound -= resultHandler; this.CancelSearch(); } }; try { lock (this.SearchLock) { // Add our handler and start the async search this.ResultFound += resultHandler; this.SearchAsync(destinations); } // Wait until our search is complete this.WaitForSearch(); } finally { // Make sure we remove our handler when we're done this.ResultFound -= resultHandler; } return(result); }
/// <summary> /// Determines whether the specified search message is a match. /// </summary> /// <param name="msg">The search message.</param> /// <returns> /// <c>true</c> if the specified search message is a match; otherwise, <c>false</c>. /// </returns> public virtual bool IsMatch(SsdpMessage msg) { if (msg.SearchType == Protocol.SsdpAll) { return(true); } if (msg.SearchType.StartsWith("uuid:") && msg.SearchType == this.USN) { return(true); } if (msg.SearchType == this.NotificationType) { return(true); } return(false); }
/// <summary> /// Gets the matching responders. /// </summary> /// <param name="msg">The MSG.</param> /// <returns></returns> public IEnumerable <ISsdpAnnouncer> GetMatchingResponders(SsdpMessage msg) { lock (this.Announcers) { foreach (var pair in this.Announcers.Where(pair => pair.Value)) { if (msg.SearchType == Protocol.SsdpAll) { yield return(pair.Key); } if (msg.SearchType.StartsWith("uuid:") && msg.SearchType == pair.Key.USN) { yield return(pair.Key); } if (msg.SearchType == pair.Key.NotificationType) { yield return(pair.Key); } } } }
protected override void OnDataReceived(NetworkData args) { base.OnDataReceived(args); // Queue this response to be processed ThreadPool.QueueUserWorkItem(data => { try { // Parse our message and fire our event var msg = SsdpMessage.Parse(args.Buffer, args.Length, args.RemoteIPEndpoint); this.OnSsdpMessageReceived(msg); } catch (ArgumentException ex) { System.Diagnostics.Trace.TraceError("Failed to parse SSDP response: {0}", ex.ToString()); } catch (Exception exception) { System.Diagnostics.Trace.TraceError("Failed to parse SSDP response: {0}", exception.ToString()); } }); }
/// <summary> /// Determines whether the specified search message is a match. /// </summary> /// <param name="msg">The search message.</param> /// <returns> /// <c>true</c> if the specified search message is a match; otherwise, <c>false</c>. /// </returns> public virtual bool IsMatch(SsdpMessage msg) { if (msg.SearchType == Protocol.SsdpAll) return true; if (msg.SearchType.StartsWith("uuid:") && msg.SearchType == this.USN) return true; if (msg.SearchType == this.NotificationType) return true; return false; }
protected virtual void OnServiceFound(SsdpMessage msg) { var handler = this.ServiceFound; if (handler != null) handler(this, new EventArgs<SsdpMessage>(msg)); }
protected virtual void OnSsdpMessageReceived(SsdpMessage ssdpMessage) { var handler = this.SsdpMessageReceived; if (handler != null) handler(this, new EventArgs<SsdpMessage>(ssdpMessage)); if (ssdpMessage.IsAlive) this.OnSsdpAlive(ssdpMessage); else if (ssdpMessage.IsByeBye) this.OnSsdpByeBye(ssdpMessage); }
/// <summary> /// Sends the search response message. /// </summary> protected void SendSearchResponse(SsdpMessage msg, ISsdpAnnouncer announcer) { this.Sockets.ForEachSocket(socket => { // If we were stopped then don't bother sending this message if (!socket.IsListening) return; var aliveResponse = Protocol.CreateAliveResponse(socket.Location.ToString(), msg.SearchType, announcer.USN, announcer.MaxAge, Protocol.DefaultUserAgent); var bytes = Encoding.ASCII.GetBytes(aliveResponse); Trace.WriteLine(string.Format("Sending SearchResponse [{0}, {1}] from {2} to {3}", msg.SearchType, msg.USN, socket.LocalEndpoint, msg.Source), AppInfo.Application); socket.Send(bytes, bytes.Length, msg.Source); }); }
protected override void OnSsdpMessageReceived(SsdpMessage msg) { base.OnSsdpMessageReceived(msg); // Ignore any advertisements if (msg.IsAdvertisement) return; // Set up our dispatcher to send the response to each matching announcer that supports responding foreach (var announcer in this.GetMatchingResponders(msg)) { var temp = announcer; Dispatcher.Add(() => this.SendSearchResponse(msg, temp), TimeSpan.FromSeconds(new Random().Next(0, msg.MaxAge))); } }
/// <summary> /// Called when [result found]. /// </summary> /// <param name="result">The result.</param> protected virtual void OnResultFound(SsdpMessage result) { // This is a search so ignore any advertisements we get if (result.IsAdvertisement) return; // If this is not a notify message then ignore it if (result.IsRequest) return; // Check to make sure this message matches our filter var filter = this.Filter; if (!filter(result)) return; var handler = this.ResultFound; if (handler != null) handler(this, new EventArgs<SsdpMessage>(result)); }
/// <summary> /// Occurs when SSDP bye bye /// </summary> /// <param name="msg"></param> protected virtual void OnByeBye(SsdpMessage msg) { var handler = this.ByeBye; if (handler != null) handler(this, new EventArgs<SsdpMessage>(msg)); }
/// <summary> /// Parses the specified reader. /// </summary> /// <param name="reader">The reader.</param> /// <param name="endPoint">The end point.</param> /// <returns></returns> public static SsdpMessage Parse(TextReader reader, IPEndPoint endPoint) { var message = new SsdpMessage(endPoint); message.FromStream(reader); return message; }
/// <summary> /// Parses the specified reader. /// </summary> /// <param name="reader">The reader.</param> /// <param name="source">The source.</param> /// <param name="destination">The destination.</param> /// <returns></returns> public static SsdpMessage Parse(TextReader reader, IPEndPoint source, IPEndPoint destination) { var message = new SsdpMessage(true, source, destination); message.FromStream(reader); return message; }
static bool IsRootAnnouncement(SsdpMessage msg) { return msg.IsRoot && msg.Type == "upnp:rootdevice" && msg.USN == "uuid:979F4CE8-64AF-4653-B207-D7514908356F::upnp:rootdevice"; }
static bool IsTestAnnouncement(SsdpMessage msg) { return msg.IsService && msg.Type == "urn:schemas-upnp-org:service:test:1" && msg.USN == "uuid:979F4CE8-64AF-4653-B207-D7514908356F::urn:schemas-upnp-org:service:test:1"; }
/// <summary> /// Called when an SSDP message is received. /// </summary> /// <param name="msg">The message.</param> protected virtual void OnSsdpMessageReceived(SsdpMessage msg) { var handler = this.SsdpMessageReceived; if (handler != null) handler(this, new EventArgs<SsdpMessage>(msg)); }
/// <summary> /// Sends the search response message. /// </summary> protected void SendSearchResponse(SsdpMessage msg, SsdpAnnouncer announcer) { lock (this.Server) { // If we were stopped then don't bother sending this message if (!this.Server.IsListening) return; byte[] bytes = Encoding.ASCII.GetBytes(Protocol.CreateAliveResponse( announcer.Location, msg.SearchType, announcer.USN, announcer.MaxAge, Protocol.DefaultUserAgent)); ; this.Server.Send(bytes, bytes.Length, msg.Source); } }