예제 #1
0
        public void SendTo(byte[] messageData, UdpEndPoint endPoint)
        {
            if (messageData == null) throw new ArgumentNullException("messageData");
            if (endPoint == null) throw new ArgumentNullException("endPoint");

            ThrowIfDisposed();

            var signal = new System.Threading.ManualResetEvent(false);
            try
            {
                _UdpClient.BeginSendToGroup(messageData, 0, messageData.Length,
                    (asyncResult) =>
                    {
                        _UdpClient.EndSendToGroup(asyncResult);
                        signal.Set();
                    }
                    , null
                );
                signal.WaitOne();
            }
            finally
            {
                signal.Dispose();
            }
        }
예제 #2
0
파일: UdpSocket.cs 프로젝트: noex/RSSDP
        public void SendTo(byte[] messageData, UdpEndPoint endPoint)
        {
            ThrowIfDisposed();

            if (messageData == null) throw new ArgumentNullException("messageData");
            if (endPoint == null) throw new ArgumentNullException("endPoint");

            _Socket.SendTo(messageData, new System.Net.IPEndPoint(IPAddress.Parse(endPoint.IPAddress), endPoint.Port));
        }
예제 #3
0
파일: UdpSocket.cs 프로젝트: noex/RSSDP
        public void SendTo(byte[] messageData, UdpEndPoint endPoint)
        {
            if (messageData == null) throw new ArgumentNullException("messageData");
            if (endPoint == null) throw new ArgumentNullException("endPoint");

            ThrowIfDisposed();

            var args = new SocketAsyncEventArgs();
            try
            {
                args.SetBuffer(messageData, 0, messageData.Length);
                args.RemoteEndPoint = new System.Net.IPEndPoint(IPAddress.Parse(endPoint.IPAddress), endPoint.Port);

                var signal = new ManualResetEvent(false);
                try
                {
                    args.Completed += (sender, e) =>
                    {
                        signal.Set();
                    };

                    _Socket.SendToAsync(args);

                    signal.WaitOne();
                }
                finally
                {
                    signal.Dispose();
                }
            }
            catch
            {
                if (args != null)
                    args.Dispose();

                throw;
            }
        }
예제 #4
0
        private void ProcessMessage(string data, UdpEndPoint endPoint)
        {
            //Responses start with the HTTP version, prefixed with HTTP/ while
            //requests start with a method which can vary and might be one we haven't
            //seen/don't know. We'll check if this message is a request or a response
            //by checking for the static HTTP/ prefix on the start of the message.
            if (data.StartsWith("HTTP/", StringComparison.OrdinalIgnoreCase))
            {
                HttpResponseMessage responseMessage = null;
                try
                {
                    responseMessage = _ResponseParser.Parse(data);
                }
                catch (ArgumentException) { }               // Ignore invalid packets.
                catch (FormatException) { }                 // Ignore invalid packets.

                if (responseMessage != null)
                {
                    OnResponseReceived(responseMessage, endPoint);
                }
            }
            else
            {
                HttpRequestMessage requestMessage = null;
                try
                {
                    requestMessage = _RequestParser.Parse(data);
                }
                catch (ArgumentException) { }               // Ignore invalid packets.
                catch (FormatException) { }                 // Ignore invalid packets.

                if (requestMessage != null)
                {
                    OnRequestReceived(requestMessage, endPoint);
                }
            }
        }
예제 #5
0
        private void ProcessMessage(string data, UdpEndPoint endPoint)
        {
            //Responses start with the HTTP version, prefixed with HTTP/ while
            //requests start with a method which can vary and might be one we haven't
            //seen/don't know. We'll check if this message is a request or a response
            //by checking for the static HTTP/ prefix on the start of the message.
            if (data.StartsWith("HTTP/", StringComparison.OrdinalIgnoreCase))
            {
                HttpResponseMessage responseMessage = null;
                try
                {
                    responseMessage = _ResponseParser.Parse(data);
                }
                catch (ArgumentException) { } // Ignore invalid packets.

                if (responseMessage != null)
                    OnResponseReceived(responseMessage, endPoint);
            }
            else
            {
                HttpRequestMessage requestMessage = null;
                try
                {
                    requestMessage = _RequestParser.Parse(data);
                }
                catch (ArgumentException) { } // Ignore invalid packets.

                if (requestMessage != null)
                    OnRequestReceived(requestMessage, endPoint);
            }
            _MessageProcessedSignal.Set();
        }
예제 #6
0
 private void SendServiceSearchResponses(SsdpDevice device, string searchTarget, UdpEndPoint endPoint)
 {
     //uuid:device-UUID::urn:domain-name:service:serviceType:ver
     SendSearchResponse(searchTarget, device, device.Udn + "::" + searchTarget, endPoint);
 }
예제 #7
0
파일: UdpSocket.cs 프로젝트: noex/RSSDP
 public void SendTo(byte[] messageData, UdpEndPoint endPoint)
 {
     using (var stream = (_Socket.GetOutputStreamAsync(new Windows.Networking.HostName(endPoint.IPAddress), endPoint.Port.ToString()).AsTask().Result))
     {
         using (var outStream = stream.AsStreamForWrite())
         {
             outStream.Write(messageData, 0, messageData.Length);
             outStream.Flush();
         }
     }
 }
예제 #8
0
        private void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, UdpEndPoint endPoint)
        {
            var rootDevice = device.ToRootDevice();

            var message = String.Format(DeviceSearchResponseMessageFormat,
                    CacheControlHeaderFromTimeSpan(rootDevice),
                    searchTarget,
                    uniqueServiceName,
                    rootDevice.Location,
                    _OSName,
                    _OSVersion,
                    ServerVersion,
                    DateTime.UtcNow.ToString("r")
                );

            _CommsServer.SendMessage(System.Text.UTF8Encoding.UTF8.GetBytes(message), endPoint);

            WriteTrace(String.Format("Sent search response to " + endPoint.ToString()), device);
        }
예제 #9
0
        public void CommsServer_SendMessageSendsOnUnicastSocket()
        {
            var socketFactory = new MockSocketFactory();
            var server = new SsdpCommunicationsServer(socketFactory);

            string message = "Hello!";
            UdpEndPoint destination = new UdpEndPoint() { IPAddress = "192.168.1.100", Port = 1701 };
            server.SendMessage(System.Text.UTF8Encoding.UTF8.GetBytes(message), destination);

            Assert.IsNotNull(socketFactory.UnicastSocket);

            var mockSocket = socketFactory.UnicastSocket as MockSocket;
            Assert.AreEqual(message, System.Text.UTF8Encoding.UTF8.GetString(mockSocket.LastMessage));
            Assert.AreEqual(destination.IPAddress, mockSocket.LastSentTo.IPAddress);
            Assert.AreEqual(destination.Port, mockSocket.LastSentTo.Port);
        }
예제 #10
0
 /// <summary>
 /// Full constructor.
 /// </summary>
 /// <param name="message">The <see cref="HttpResponseMessage"/> that was received.</param>
 /// <param name="receivedFrom">A <see cref="UdpEndPoint"/> representing the sender's address (sometimes used for replies).</param>
 public ResponseReceivedEventArgs(HttpResponseMessage message, UdpEndPoint receivedFrom)
 {
     _Message = message;
     _ReceivedFrom = receivedFrom;
 }
예제 #11
0
        private void ProcessSearchRequest(string mx, string searchTarget, UdpEndPoint endPoint)
        {
            if (String.IsNullOrEmpty(searchTarget))
            {
                WriteTrace(String.Format("Invalid search request received From {0}, Target is null/empty.", endPoint.ToString()));
                return;
            }

            WriteTrace(String.Format("Search Request Received From {0}, Target = {1}", endPoint.ToString(), searchTarget));

            if (IsDuplicateSearchRequest(searchTarget, endPoint))
            {
                WriteTrace("Search Request is Duplicate, ignoring.");
                return;
            }

            //Wait on random interval up to MX, as per SSDP spec.
            //Also, as per UPnP 1.1/SSDP spec ignore missing/bank MX header. If over 120, assume random value between 0 and 120.
            //Using 16 as minimum as that's often the minimum system clock frequency anyway.
            int maxWaitInterval = 0;
            if (String.IsNullOrEmpty(mx))
            {
                //Windows Explorer is poorly behaved and doesn't supply an MX header value.
                if (this.SupportPnpRootDevice)
                    mx = "1";
                else
                    return;
            }

            if (!Int32.TryParse(mx, out maxWaitInterval) || maxWaitInterval <= 0) return;

            if (maxWaitInterval > 120)
                maxWaitInterval = _Random.Next(0, 120);

            //Do not block synchronously as that may tie up a threadpool thread for several seconds.
            TaskEx.Delay(_Random.Next(16, (maxWaitInterval * 1000))).ContinueWith((parentTask) =>
                {
                    //Copying devices to local array here to avoid threading issues/enumerator exceptions.
                    IEnumerable<SsdpDevice> devices = null;
                    lock (_Devices)
                    {
                        if (String.Compare(SsdpConstants.SsdpDiscoverAllSTHeader, searchTarget, StringComparison.OrdinalIgnoreCase) == 0)
                            devices = GetAllDevicesAsFlatEnumerable().ToArray();
                        else if (String.Compare(SsdpConstants.UpnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 || (this.SupportPnpRootDevice && String.Compare(SsdpConstants.PnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0))
                            devices = _Devices.ToArray();
                        else if (searchTarget.Trim().StartsWith("uuid:", StringComparison.OrdinalIgnoreCase))
                            devices = (from device in GetAllDevicesAsFlatEnumerable() where String.Compare(device.Uuid, searchTarget.Substring(5), StringComparison.OrdinalIgnoreCase) == 0 select device).ToArray();
                        else if (searchTarget.StartsWith("urn:", StringComparison.OrdinalIgnoreCase))
                            devices = (from device in GetAllDevicesAsFlatEnumerable() where String.Compare(device.FullDeviceType, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 select device).ToArray();
                    }

                    if (devices != null)
                    {
                        WriteTrace(String.Format("Sending {0} search responses", devices.Count()));

                        foreach (var device in devices)
                        {
                            SendDeviceSearchResponses(device, endPoint);
                        }
                    }
                    else
                        WriteTrace(String.Format("Sending 0 search responses."));
                });
        }
예제 #12
0
 public void SendTo(byte[] messageData, UdpEndPoint endPoint)
 {
     _LastSentTo = endPoint;
     _LastMessage = messageData;
 }
예제 #13
0
        private void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, UdpEndPoint endPoint)
        {
            var rootDevice = device.ToRootDevice();

            var    additionalheaders = FormatCustomHeadersForResponse(device);
            string message;

            if (device.Weemo)
            {
                message = String.Format(WeemoSearchResponseMessageFormat,
                                        String.Format("CACHE-CONTROL: max-age={0}", rootDevice.CacheLifetime.TotalSeconds),
                                        DateTime.UtcNow.ToString("r"),
                                        rootDevice.Location,
                                        rootDevice.SerialNumber,
                                        searchTarget,
                                        uniqueServiceName);
            }
            else
            {
                message = String.Format(DeviceSearchResponseMessageFormat,
                                        CacheControlHeaderFromTimeSpan(rootDevice),
                                        searchTarget,
                                        uniqueServiceName,
                                        rootDevice.Location,
                                        _OSName,
                                        _OSVersion,
                                        ServerVersion,
                                        DateTime.UtcNow.ToString("r"),
                                        additionalheaders);
            }
            _CommsServer.SendMessage(System.Text.UTF8Encoding.UTF8.GetBytes(message), endPoint);

            WriteTrace(String.Format("Sent search response to " + endPoint.ToString()), device);
        }
예제 #14
0
 public void MockReceive(byte[] data, UdpEndPoint fromEndPoint)
 {
     _ReceiveQueue.Enqueue(new ReceivedUdpData() { Buffer = data, ReceivedFrom = fromEndPoint, ReceivedBytes = data.Length });
     _DataAvailableSignal.Set();
 }
예제 #15
0
        public void CommsServer_StopListeningForResponsesDisposesUnicastSocket()
        {
            var socketFactory = new MockSocketFactory();
            var server = new SsdpCommunicationsServer(socketFactory);

            string message = "Hello!";
            UdpEndPoint destination = new UdpEndPoint() { IPAddress = "192.168.1.100", Port = 1701 };
            server.SendMessage(System.Text.UTF8Encoding.UTF8.GetBytes(message), destination);

            var mockSocket = socketFactory.UnicastSocket as MockSocket;

            Assert.IsFalse(mockSocket.IsDisposed);

            server.StopListeningForResponses();

            Assert.IsTrue(mockSocket.IsDisposed);
        }
예제 #16
0
        public void CommsServer_SendNullMulticastMessageThrowsException()
        {
            var socketFactory = new MockSocketFactory();
            var server = new SsdpCommunicationsServer(socketFactory);

            UdpEndPoint destination = new UdpEndPoint() { IPAddress = "192.168.1.100", Port = 1701 };
            server.SendMulticastMessage(null);
        }
예제 #17
0
 public void SendMessage(byte[] messageData, UdpEndPoint destination)
 {
     SentMessages.Enqueue(new ReceivedUdpData() { Buffer = messageData, ReceivedBytes = messageData.Length, ReceivedFrom = destination });
     _SentMessageSignal.Set();
 }
예제 #18
0
 /// <summary>
 /// Full constructor.
 /// </summary>
 /// <param name="message">The <see cref="HttpResponseMessage"/> that was received.</param>
 /// <param name="receivedFrom">A <see cref="UdpEndPoint"/> representing the sender's address (sometimes used for replies).</param>
 public ResponseReceivedEventArgs(HttpResponseMessage message, UdpEndPoint receivedFrom)
 {
     _Message      = message;
     _ReceivedFrom = receivedFrom;
 }
예제 #19
0
        private bool IsDuplicateSearchRequest(string searchTarget, UdpEndPoint endPoint)
        {
            var isDuplicateRequest = false;

            var newRequest = new SearchRequest() { EndPoint = endPoint, SearchTarget = searchTarget, Received = DateTime.UtcNow };
            lock (_RecentSearchRequests)
            {
                if (_RecentSearchRequests.ContainsKey(newRequest.Key))
                {
                    var lastRequest = _RecentSearchRequests[newRequest.Key];
                    if (lastRequest.IsOld())
                        _RecentSearchRequests[newRequest.Key] = newRequest;
                    else
                        isDuplicateRequest = true;
                }
                else
                {
                    _RecentSearchRequests.Add(newRequest.Key, newRequest);
                    if (_RecentSearchRequests.Count > 10)
                        CleanUpRecentSearchRequestsAsync();
                }
            }

            return isDuplicateRequest;
        }
예제 #20
0
        private void ProcessSearchRequest(string mx, string searchTarget, UdpEndPoint endPoint)
        {
            if (String.IsNullOrEmpty(searchTarget))
            {
                WriteTrace(String.Format("Invalid search request received From {0}, Target is null/empty.", endPoint.ToString()));
                return;
            }

            WriteTrace(String.Format("Search Request Received From {0}, Target = {1}", endPoint.ToString(), searchTarget));

            if (IsDuplicateSearchRequest(searchTarget, endPoint))
            {
                WriteTrace("Search Request is Duplicate, ignoring.");
                return;
            }

            //Wait on random interval up to MX, as per SSDP spec.
            //Also, as per UPnP 1.1/SSDP spec ignore missing/bank MX header. If over 120, assume random value between 0 and 120.
            //Using 16 as minimum as that's often the minimum system clock frequency anyway.
            int maxWaitInterval = 0;

            if (String.IsNullOrEmpty(mx))
            {
                //Windows Explorer is poorly behaved and doesn't supply an MX header value.
                if (this.SupportPnpRootDevice)
                {
                    mx = "1";
                }
                else
                {
                    return;
                }
            }

            if (!Int32.TryParse(mx, out maxWaitInterval) || maxWaitInterval <= 0)
            {
                return;
            }

            if (maxWaitInterval > 120)
            {
                maxWaitInterval = _Random.Next(0, 120);
            }

            //Do not block synchronously as that may tie up a threadpool thread for several seconds.
            TaskEx.Delay(_Random.Next(16, (maxWaitInterval * 1000))).ContinueWith((parentTask) =>
            {
                //Copying devices to local array here to avoid threading issues/enumerator exceptions.
                IEnumerable <SsdpDevice> devices = null;
                lock (_Devices)
                {
                    if (String.Compare(SsdpConstants.SsdpDiscoverAllSTHeader, searchTarget, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        devices = GetAllDevicesAsFlatEnumerable().ToArray();
                    }
                    else if (String.Compare(SsdpConstants.UpnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 || (this.SupportPnpRootDevice && String.Compare(SsdpConstants.PnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0))
                    {
                        devices = _Devices.ToArray();
                    }
                    else if (searchTarget.Trim().StartsWith("uuid:", StringComparison.OrdinalIgnoreCase))
                    {
                        devices = (from device in GetAllDevicesAsFlatEnumerable() where String.Compare(device.Uuid, searchTarget.Substring(5), StringComparison.OrdinalIgnoreCase) == 0 select device).ToArray();
                    }
                    else if (searchTarget.StartsWith("urn:", StringComparison.OrdinalIgnoreCase))
                    {
                        devices = (from device in GetAllDevicesAsFlatEnumerable() where String.Compare(device.FullDeviceType, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 select device).ToArray();
                    }
                }

                if (devices != null)
                {
                    WriteTrace(String.Format("Sending {0} search responses", devices.Count()));

                    foreach (var device in devices)
                    {
                        SendDeviceSearchResponses(device, endPoint);
                    }
                }
                else
                {
                    WriteTrace(String.Format("Sending 0 search responses."));
                }
            });
        }
예제 #21
0
        private void SendDeviceSearchResponses(SsdpDevice device, UdpEndPoint endPoint)
        {
            bool isRootDevice = (device as SsdpRootDevice) != null;
            if (isRootDevice)
            {
                SendSearchResponse(SsdpConstants.UpnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.UpnpDeviceTypeRootDevice), endPoint);
                if (this.SupportPnpRootDevice)
                    SendSearchResponse(SsdpConstants.PnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.PnpDeviceTypeRootDevice), endPoint);
            }

            SendSearchResponse(device.Udn, device, device.Udn, endPoint);

            SendSearchResponse(device.FullDeviceType, device, GetUsn(device.Udn, device.FullDeviceType), endPoint);
        }
예제 #22
0
        private void ProcessSearchRequest(string mx, string searchTarget, UdpEndPoint endPoint)
        {
            if (String.IsNullOrEmpty(searchTarget))
            {
                _Log.LogWarning(String.Format("Invalid search request received From {0}, Target is null/empty.", endPoint.ToString()));
                return;
            }

            _Log.LogInfo(String.Format("Search Request Received From {0}, Target = {1}", endPoint.ToString(), searchTarget));

            if (IsDuplicateSearchRequest(searchTarget, endPoint))
            {
                Log.LogWarning("Search Request is Duplicate, ignoring.");
                return;
            }

            //Wait on random interval up to MX, as per SSDP spec.
            //Also, as per UPnP 1.1/SSDP spec ignore missing/bank MX header (strict mode only). If over 120, assume random value between 0 and 120.
            //Using 16 as minimum as that's often the minimum system clock frequency anyway.
            int maxWaitInterval = 0;

            if (String.IsNullOrEmpty(mx))
            {
                //Windows Explorer is poorly behaved and doesn't supply an MX header value.
                if (IsWindowsExplorerSupportEnabled)
                {
                    mx = "1";
                }
                else
                {
                    _Log.LogWarning("Search Request ignored due to missing MX header. Set StandardsMode to relaxed to respond to these requests.");
                    return;
                }
            }

            if (!Int32.TryParse(mx, out maxWaitInterval) || maxWaitInterval <= 0)
            {
                return;
            }

            if (maxWaitInterval > 120)
            {
                maxWaitInterval = _Random.Next(0, 120);
            }

            //Do not block synchronously as that may tie up a threadpool thread for several seconds.
            TaskEx.Delay(_Random.Next(16, (maxWaitInterval * 1000))).ContinueWith((parentTask) =>
            {
                //Copying devices to local array here to avoid threading issues/enumerator exceptions.
                IEnumerable <SsdpDevice> devices = null;
                devices = GetDevicesMatchingSearchTarget(searchTarget, devices);

                if (devices != null)
                {
                    SendSearchResponses(searchTarget, endPoint, devices);
                }
                else
                {
                    _Log.LogWarning("Sending search responses for 0 devices (no matching targets).");
                }
            });
        }
예제 #23
0
        /// <summary>
        /// Sends a message to a particular address (uni or multicast) and port.
        /// </summary>
        /// <param name="messageData">A byte array containing the data to send.</param>
        /// <param name="destination">A <see cref="UdpEndPoint"/> representing the destination address for the data. Can be either a multicast or unicast destination.</param>
        /// <exception cref="System.ArgumentNullException">Thrown if the <paramref name="messageData"/> argument is null.</exception>
        /// <exception cref="System.ObjectDisposedException">Thrown if the <see cref="DisposableManagedObjectBase.IsDisposed"/> property is true (because <seealso cref="DisposableManagedObjectBase.Dispose()" /> has been called previously).</exception>
        public void SendMessage(byte[] messageData, UdpEndPoint destination)
        {
            if (messageData == null) throw new ArgumentNullException("messageData");

            ThrowIfDisposed();

            EnsureSendSocketCreated();

            // SSDP spec recommends sending messages multiple times (not more than 3) to account for possible packet loss over UDP.
            Repeat(SsdpConstants.UdpResendCount, TimeSpan.FromMilliseconds(100), () =>
                {
                    SendMessageIfSocketNotDisposed(messageData, destination);
                });
        }
예제 #24
0
 /// <summary>
 /// Full constructor.
 /// </summary>
 /// <param name="message">The <see cref="HttpRequestMessage"/> that was received.</param>
 /// <param name="receivedFrom">A <see cref="UdpEndPoint"/> representing the sender's address (sometimes used for replies).</param>
 public RequestReceivedEventArgs(HttpRequestMessage message, UdpEndPoint receivedFrom)
 {
     _Message = message;
     _ReceivedFrom = receivedFrom;
 }
예제 #25
0
        private void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, UdpEndPoint endPoint)
        {
            var rootDevice = device.ToRootDevice();

            var message = String.Format(DeviceSearchResponseMessageFormat,
                                        CacheControlHeaderFromTimeSpan(rootDevice),
                                        searchTarget,
                                        uniqueServiceName,
                                        rootDevice.Location,
                                        _OSName,
                                        _OSVersion,
                                        ServerVersion,
                                        DateTime.UtcNow.ToString("r")
                                        );

            _CommsServer.SendMessage(System.Text.UTF8Encoding.UTF8.GetBytes(message), endPoint);

            WriteTrace(String.Format("Sent search response to " + endPoint.ToString()), device);
        }
예제 #26
0
 private void SendMessageIfSocketNotDisposed(byte[] messageData, UdpEndPoint destination)
 {
     var socket = _SendSocket;
     if (socket != null)
     {
         _SendSocket.SendTo(messageData, destination);
     }
     else
     {
         ThrowIfDisposed();
     }
 }
예제 #27
0
        private void SendDeviceSearchResponses(SsdpDevice device, string searchTarget, UdpEndPoint endPoint)
        {
            //http://www.upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.0-20080424.pdf - page 21
            //For ssdp:all - Respond 3+2d+k times for a root device with d embedded devices and s embedded services but only k distinct service types
            //Root devices - Respond once (special handling when in related/Win Explorer support mode)
            //Udn (uuid) - Response once
            //Device type - response once
            //Service type - respond once per service type

            bool isRootDevice    = (device as SsdpRootDevice) != null;
            bool sendAll         = searchTarget == SsdpConstants.SsdpDiscoverAllSTHeader;
            bool sendRootDevices = searchTarget == SsdpConstants.UpnpDeviceTypeRootDevice || searchTarget == SsdpConstants.PnpDeviceTypeRootDevice;

            if (isRootDevice && (sendAll || sendRootDevices))
            {
                SendSearchResponse(SsdpConstants.UpnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.UpnpDeviceTypeRootDevice), endPoint);
                if (IsWindowsExplorerSupportEnabled)
                {
                    SendSearchResponse(SsdpConstants.PnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.PnpDeviceTypeRootDevice), endPoint);
                }
            }

            if (sendAll || searchTarget.StartsWith("uuid:", StringComparison.Ordinal))
            {
                SendSearchResponse(device.Udn, device, device.Udn, endPoint);
            }

            if (sendAll || searchTarget.Contains(":device:"))
            {
                SendSearchResponse(device.FullDeviceType, device, GetUsn(device.Udn, device.FullDeviceType), endPoint);
            }

            if (searchTarget == SsdpConstants.SsdpDiscoverAllSTHeader)
            {
                //Send 1 search response for each unique service type for all devices found
                var serviceTypes =
                    (
                        from s
                        in device.Services
                        select s.FullServiceType
                    ).Distinct().ToArray();

                foreach (var st in serviceTypes)
                {
                    SendServiceSearchResponses(device, st, endPoint);
                }
            }
        }
예제 #28
0
 /// <summary>
 /// Full constructor.
 /// </summary>
 /// <param name="message">The <see cref="HttpRequestMessage"/> that was received.</param>
 /// <param name="receivedFrom">A <see cref="UdpEndPoint"/> representing the sender's address (sometimes used for replies).</param>
 public RequestReceivedEventArgs(HttpRequestMessage message, UdpEndPoint receivedFrom)
 {
     _Message      = message;
     _ReceivedFrom = receivedFrom;
 }
예제 #29
0
        private void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, UdpEndPoint endPoint)
        {
            var rootDevice = device.ToRootDevice();

            var additionalheaders = FormatCustomHeadersForResponse(device);

            var message = String.Format(DeviceSearchResponseMessageFormat,
                                        CacheControlHeaderFromTimeSpan(rootDevice),
                                        searchTarget,
                                        uniqueServiceName,
                                        rootDevice.Location,
                                        _OSName,
                                        _OSVersion,
                                        ServerVersion,
                                        DateTime.UtcNow.ToString("r"),
                                        additionalheaders
                                        );

            _CommsServer.SendMessage(System.Text.UTF8Encoding.UTF8.GetBytes(message), endPoint);

            LogDeviceEventVerbose(String.Format("Sent search response ({0}) to {1}", uniqueServiceName, endPoint.ToString()), device);
        }
예제 #30
0
        private void OnRequestReceived(HttpRequestMessage data, UdpEndPoint endPoint)
        {
            //SSDP specification says only * is currently used but other uri's might
            //be implemented in the future and should be ignored unless understood.
            //Section 4.2 - http://tools.ietf.org/html/draft-cai-ssdp-v1-03#page-11
            if (data.RequestUri.ToString() != "*") return;

            var handlers = this.RequestReceived;
            if (handlers != null)
                handlers(this, new RequestReceivedEventArgs(data, endPoint));
        }
예제 #31
0
 private void OnResponseReceived(HttpResponseMessage data, UdpEndPoint endPoint)
 {
     var handlers = this.ResponseReceived;
     if (handlers != null)
         handlers(this, new ResponseReceivedEventArgs(data, endPoint));
 }
예제 #32
0
        private void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, UdpEndPoint endPoint)
        {
            if (device is SsdpHueBridgeDevice)
            {
                var hueDevice     = device as SsdpHueBridgeDevice;
                var messageHeader = String.Format(SsdpHueBridgeDevice.HUE_RESPONSE,
                                                  hueDevice.HttpServerIpAddress,
                                                  hueDevice.HttpServerPort,
                                                  hueDevice.HttpServerOptionalSubFolder,
                                                  hueDevice.HueBridgeId
                                                  );
                var message1 = messageHeader + String.Format(SsdpHueBridgeDevice.HUE_ST1, hueDevice.HueUuid);
                Debug.WriteLine("Sending packet 1: " + message1);
                var message2 = messageHeader + String.Format(SsdpHueBridgeDevice.HUE_ST2, hueDevice.HueUuid);
                Debug.WriteLine("Sending packet 2:" + message2);
                var message3 = messageHeader + String.Format(SsdpHueBridgeDevice.HUE_ST3, hueDevice.HueUuid);
                Debug.WriteLine("Sending packet 3: " + message3);
                _CommsServer.SendMessage(Encoding.UTF8.GetBytes(message1), endPoint);
                _CommsServer.SendMessage(Encoding.UTF8.GetBytes(message2), endPoint);
                _CommsServer.SendMessage(Encoding.UTF8.GetBytes(message3), endPoint);
            }
            else
            {
                var rootDevice = device.ToRootDevice();

                var additionalheaders = FormatCustomHeadersForResponse(device);

                var message = String.Format(DeviceSearchResponseMessageFormat,
                                            CacheControlHeaderFromTimeSpan(rootDevice),
                                            searchTarget,
                                            uniqueServiceName,
                                            rootDevice.Location,
                                            _OSName,
                                            _OSVersion,
                                            ServerVersion,
                                            DateTime.UtcNow.ToString("r"),
                                            additionalheaders
                                            );

                _CommsServer.SendMessage(System.Text.UTF8Encoding.UTF8.GetBytes(message), endPoint);
            }

            LogDeviceEventVerbose(String.Format("Sent search response ({0}) to {1}", uniqueServiceName, endPoint.ToString()), device);
        }