예제 #1
0
파일: Rssdp.cs 프로젝트: jeason0813/Antd
        public static void PublishThisDevice(string ip)
        {
            if (string.IsNullOrEmpty(ip))
            {
                ConsoleLogger.Log("[rssdp] cannot publish device: ip address not valid");
                return;
            }
            var appPort          = Application.CurrentConfiguration.WebService.GuiWebServicePort;
            var deviceDefinition = new SsdpRootDevice()
            {
                CacheLifetime       = TimeSpan.FromMinutes(30),
                Uuid                = Application.CurrentConfiguration.Host.MachineUid.ToString(),
                Location            = new Uri($"http://{ip}:{appPort}/device/description"),
                DeviceTypeNamespace = "antd",
                ModelUrl            = new Uri($"http://{ip}:{appPort}/"),
                DeviceType          = Application.CurrentConfiguration.Host.PartNumber.ToString(),
                FriendlyName        = $"{ip} as {Application.CurrentConfiguration.Host.HostName}",
                Manufacturer        = "Anthilla SRL",
                ModelName           = Application.CurrentConfiguration.Host.SerialNumber.ToString().Replace("-", ""),
                SerialNumber        = Application.CurrentConfiguration.Host.SerialNumber.ToString()
            };

            _Publisher = new SsdpDevicePublisher();
            _Publisher.AddDevice(deviceDefinition);
            ConsoleLogger.Log($"[rssdp] publishing this device on '{ip}'");
        }
예제 #2
0
        // Call this method from somewhere to actually do the publish.
        private static void PublishDevice()
        {
            var ip4     = GetLocalIp4Address();
            var version = Assembly.GetExecutingAssembly().GetName().Version.ToString();

            var deviceDefinition4 = new SsdpRootDevice()
            {
                Location        = new Uri($"http://{ip4}/home/service"),
                PresentationUrl = new Uri($"http://{ip4}/"),
                FriendlyName    = "Milwaukee Makerspace Api",
                Manufacturer    = "Milwaukee Makerspace",
                ModelName       = "Milwaukee Makerspace Api",
                Uuid            = "6111f321-2cee-455e-b203-4abfaf14b516",
                ManufacturerUrl = new Uri("https://milwaukeemakerspace.org/"),
                ModelUrl        = new Uri("https://github.com/DanDude0/MilwaukeeMakerspaceApi/"),
                ModelNumber     = version,
            };

            // Have to bind to all addresses on Linux, or broadcasts don't work!
            if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows))
            {
                ip4 = IPAddress.Any.ToString();
            }

            Console.WriteLine($"Publishing SSDP on {ip4}");

            SsdpPublisher4 = new SsdpDevicePublisher(new SsdpCommunicationsServer(new SocketFactory(ip4)));
            SsdpPublisher4.StandardsMode = SsdpStandardsMode.Relaxed;
            SsdpPublisher4.AddDevice(deviceDefinition4);

            SsdpDescription = deviceDefinition4.ToDescriptionDocument();
        }
예제 #3
0
        private async Task RegisterServerEndpoints()
        {
            var cacheLength = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds;

            var addresses = (await _appHost.GetLocalIpAddresses(CancellationToken.None).ConfigureAwait(false)).ToList();

            var udn = CreateUuid(_appHost.SystemId);

            foreach (var address in addresses)
            {
                // TODO: Remove this condition on platforms that support it
                //if (address.AddressFamily == IpAddressFamily.InterNetworkV6)
                //{
                //    continue;
                //}

                var fullService = "urn:schemas-upnp-org:device:MediaServer:1";

                _logger.Info("Registering publisher for {0} on {1}", fullService, address.ToString());

                var descriptorUri = "/dlna/" + udn + "/description.xml";
                var uri           = new Uri(_appHost.GetLocalApiUrl(address) + descriptorUri);

                var device = new SsdpRootDevice
                {
                    CacheLifetime = TimeSpan.FromSeconds(cacheLength), //How long SSDP clients can cache this info.
                    Location      = uri,                               // Must point to the URL that serves your devices UPnP description document.
                    FriendlyName  = "Emby Server",
                    Manufacturer  = "Emby",
                    ModelName     = "Emby Server",
                    Uuid          = udn
                                    // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
                };

                SetProperies(device, fullService);
                _Publisher.AddDevice(device);

                var embeddedDevices = new []
                {
                    "urn:schemas-upnp-org:service:ContentDirectory:1",
                    "urn:schemas-upnp-org:service:ConnectionManager:1",
                    //"urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1"
                };

                foreach (var subDevice in embeddedDevices)
                {
                    var embeddedDevice = new SsdpEmbeddedDevice
                    {
                        FriendlyName = device.FriendlyName,
                        Manufacturer = device.Manufacturer,
                        ModelName    = device.ModelName,
                        Uuid         = udn
                                       // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
                    };

                    SetProperies(embeddedDevice, subDevice);
                    device.AddDevice(embeddedDevice);
                }
            }
        }
예제 #4
0
파일: Program.cs 프로젝트: sk8tz/RSSDP
        private static void PublishDevices()
        {
            if (_DevicePublisher != null)
            {
                Console.WriteLine("Stopping previous publisher.");
                _DevicePublisher.Dispose();
            }

            // Create a device publisher
            _DevicePublisher = new SsdpDevicePublisher();

            // Create the device(s) we want to publish.
            var rootDevice = new SsdpRootDevice()
            {
                CacheLifetime = TimeSpan.FromMinutes(30),
                FriendlyName  = "Sample RSSDP Device",
                Manufacturer  = "RSSDP",
                ModelNumber   = "123",
                ModelName     = "RSSDP Sample Device",
                SerialNumber  = "123",
                Uuid          = System.Guid.NewGuid().ToString()
            };

            rootDevice.CustomResponseHeaders.Add(new CustomHttpHeader("X-MachineName", Environment.MachineName));

            // Now publish by adding them to the publisher.
            _DevicePublisher.AddDevice(rootDevice);

            Console.WriteLine("Publishing devices: ");
            WriteOutDevices(rootDevice);
            Console.WriteLine();
        }
예제 #5
0
        private async Task RegisterServerEndpoints()
        {
            var addresses = await _appHost.GetLocalIpAddresses(CancellationToken.None).ConfigureAwait(false);

            var udn = CreateUuid(_appHost.SystemId);

            foreach (var address in addresses)
            {
                if (address.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    // Not support IPv6 right now
                    continue;
                }

                var fullService = "urn:schemas-upnp-org:device:MediaServer:1";

                _logger.LogInformation("Registering publisher for {0} on {1}", fullService, address);

                var descriptorUri = "/dlna/" + udn + "/description.xml";
                var uri           = new Uri(_appHost.GetLocalApiUrl(address) + descriptorUri);

                var device = new SsdpRootDevice
                {
                    CacheLifetime = TimeSpan.FromSeconds(1800), //How long SSDP clients can cache this info.
                    Location      = uri,                        // Must point to the URL that serves your devices UPnP description document.
                    Address       = address,
                    SubnetMask    = _networkManager.GetLocalIpSubnetMask(address),
                    FriendlyName  = "Veso",
                    Manufacturer  = "Veso",
                    ModelName     = "Veso Server",
                    Uuid          = udn
                                    // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
                };

                SetProperies(device, fullService);
                _Publisher.AddDevice(device);

                var embeddedDevices = new[]
                {
                    "urn:schemas-upnp-org:service:ContentDirectory:1",
                    "urn:schemas-upnp-org:service:ConnectionManager:1",
                    //"urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1"
                };

                foreach (var subDevice in embeddedDevices)
                {
                    var embeddedDevice = new SsdpEmbeddedDevice
                    {
                        FriendlyName = device.FriendlyName,
                        Manufacturer = device.Manufacturer,
                        ModelName    = device.ModelName,
                        Uuid         = udn
                                       // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
                    };

                    SetProperies(embeddedDevice, subDevice);
                    device.AddDevice(embeddedDevice);
                }
            }
        }
예제 #6
0
        private async void Page_Loaded(object sender, RoutedEventArgs e)
        {
            //Note, you can use deviceDefinition.ToDescriptionDocumentText() to retrieve the data to
            //return from the Location end point, you just need to get that data to your service
            //implementation somehow. Depends on how you've implemented your service.

            _Publisher = new SsdpDevicePublisher();
            _device    = PublishDevice();
            _Publisher.AddDevice(_device);

            await StartWebserverAsync();
        }
예제 #7
0
        public Controller()
        {
            _Publisher = new SsdpDevicePublisher();
            var deviceDefinition = new SsdpRootDevice()
            {
                CacheLifetime       = TimeSpan.FromMinutes(30),                           //How long SSDP clients can cache this info.
                Location            = new Uri("http://mydevice/descriptiondocument.xml"), // Must point to the URL that serves your devices UPnP description document.
                DeviceTypeNamespace = "my-namespace",
                DeviceType          = "MyCustomDevice",
                FriendlyName        = "Custom Device 1",
                Manufacturer        = "Me",
                ModelName           = "MyCustomDevice",
                Uuid = "Andrew-PC" // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
            };

            _Publisher.AddDevice(deviceDefinition);
        }
예제 #8
0
        public void PublishDevice()
        {
            // As this is a sample, we are only setting the minimum required properties.
            Device = new SsdpRootDevice()
            {
                CacheLifetime       = TimeSpan.FromMinutes(30),
                Location            = Location,
                DeviceTypeNamespace = DeviceTypeNamespace,
                DeviceType          = DeviceTypeName,
                FriendlyName        = $"Automatica.Core Server ({ServerInfo.GetServerVersion()})",
                Manufacturer        = "p3root",
                ModelName           = "Automatica.Core Server",
                Uuid = AutomaticaUuid
            };

            Device.CustomProperties.Add(new SsdpDeviceProperty()
            {
                Name      = "URL",
                Namespace = "server-url",
                Value     = $"http://{NetworkHelper.GetActiveIp()}:{_port}"
            });

            Device.CustomResponseHeaders.Add(new CustomHttpHeader("server-url", $"http://{NetworkHelper.GetActiveIp()}:{_port}"));


            Device.CustomProperties.Add(new SsdpDeviceProperty()
            {
                Name      = "Version",
                Namespace = "server-version",
                Value     = ServerInfo.GetServerVersion()
            });

            Device.CustomResponseHeaders.Add(new CustomHttpHeader("server-version", ServerInfo.GetServerVersion()));

            Device.CustomProperties.Add(new SsdpDeviceProperty()
            {
                Name      = "Name",
                Namespace = "server-name",
                Value     = $"Automatica.Core XYZ"
            });

            Device.CustomResponseHeaders.Add(new CustomHttpHeader("server-name", $"Automatica.Core XYZ"));

            _publisher?.AddDevice(Device);
        }
예제 #9
0
        public void Start()
        {
            var deviceDefinition = new SsdpRootDevice()
            {
                CacheLifetime       = TimeSpan.FromHours(1),
                Location            = new Uri("http://wirehome.local/upnp.xml"), // TODO: Must point to the URL that serves your devices UPnP description document.
                DeviceTypeNamespace = "my-namespace",
                DeviceType          = "Wirehome.Core",
                FriendlyName        = "Wirehome Core",
                Manufacturer        = "Christian Kratky",
                ModelName           = "Wirehome.Core",
                Uuid = "uuid:c6faa85a-d7e9-48b7-8c54-7459c4d9c329"
            };

            _publisher.AddDevice(deviceDefinition);

            Task.Run(() => SearchAsync(_systemCancellationToken.Token), _systemCancellationToken.Token);
        }
예제 #10
0
        private static void PublishDevices()
        {
            if (_DevicePublisher != null)
            {
                Console.WriteLine("Stopping previous publisher.");
                _DevicePublisher.Dispose();
            }

            // Create a device publisher
            _DevicePublisher = new SsdpDevicePublisher();

            // Create the device(s) we want to publish.
            var rootDevice = new SsdpRootDevice()
            {
                CacheLifetime = TimeSpan.FromMinutes(30),
                FriendlyName  = "Sample RSSDP Device",
                Manufacturer  = "RSSDP",
                ModelNumber   = "123",
                ModelName     = "RSSDP Sample Device",
                SerialNumber  = "123",
                Uuid          = System.Guid.NewGuid().ToString()
            };

            rootDevice.CustomResponseHeaders.Add(new CustomHttpHeader("X-MachineName", Environment.MachineName));

            var service = new SsdpService()
            {
                Uuid                 = System.Guid.NewGuid().ToString(),
                ServiceType          = "test-service-type",
                ServiceTypeNamespace = "rssdp-test-namespace",
                ControlUrl           = new Uri("/test/control", UriKind.Relative),
                EventSubUrl          = new Uri("/test/event", UriKind.Relative),
                ScpdUrl              = new Uri("/test", UriKind.Relative)
            };

            rootDevice.AddService(service);

            // Now publish by adding them to the publisher.
            _DevicePublisher.AddDevice(rootDevice);

            Console.WriteLine("Publishing devices: ");
            WriteOutDevices(rootDevice);
            Console.WriteLine();
        }
예제 #11
0
        public static void PublishThisDevice()
        {
            var appPort  = new AppConfiguration().Get().AntdUiPort;
            var localIps = IPv4.GetAllLocalAddress().Where(_ => _ != "127.0.0.1").OrderBy(_ => _).ToList();

            foreach (var ip in localIps)
            {
                var deviceDefinition = new SsdpRootDevice()
                {
                    CacheLifetime       = TimeSpan.FromMinutes(60),
                    Uuid                = MachineUid,
                    Location            = new Uri($"http://{ip}:{appPort}/device/description"),
                    DeviceTypeNamespace = "antd",
                    ModelUrl            = new Uri($"http://{ip}:{appPort}/"),
                    DeviceType          = PartNumber,
                    FriendlyName        = $"{ip} as {Hostname}",
                    Manufacturer        = "Anthilla SRL",
                    ModelName           = SerialNumber
                };
                _Publisher = new SsdpDevicePublisher();
                _Publisher.AddDevice(deviceDefinition);
            }
        }
예제 #12
0
        public void Publish()
        {
            // As this is a sample, we are only setting the minimum required properties.
            SsdpRootDevice deviceDefinition = new SsdpRootDevice()
            {
                CacheLifetime = TimeSpan.FromMinutes(30), //How long SSDP clients can cache this info.
                //Location = new Uri("http://mydevice/descriptiondocument.xml"), // Must point to the URL that serves your devices UPnP description document.
                DeviceTypeNamespace = "my-namespace",
                DeviceType          = "BattleShip.Server",
                FriendlyName        = "Battleship Server",
                Manufacturer        = "Me",
                ModelName           = "MyCustomDevice",
                Uuid = m_StorageManager.InstanceID.ToString() // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
            };

            m_HTTPServer.Start(deviceDefinition);

            if (m_Publisher == null)
            {
                m_Publisher = new SsdpDevicePublisher();
            }

            m_Publisher.AddDevice(deviceDefinition);
        }
예제 #13
0
        private void RegisterServerEndpoints()
        {
            var udn           = CreateUuid(_appHost.SystemId);
            var descriptorUri = "/dlna/" + udn + "/description.xml";

            var bindAddresses = NetworkManager.CreateCollection(
                _networkManager.GetInternalBindAddresses()
                .Where(i => i.AddressFamily == AddressFamily.InterNetwork || (i.AddressFamily == AddressFamily.InterNetworkV6 && i.Address.ScopeId != 0)));

            if (bindAddresses.Count == 0)
            {
                // No interfaces returned, so use loopback.
                bindAddresses = _networkManager.GetLoopbacks();
            }

            foreach (IPNetAddress address in bindAddresses)
            {
                if (address.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    // Not supporting IPv6 right now
                    continue;
                }

                // Limit to LAN addresses only
                if (!_networkManager.IsInLocalNetwork(address))
                {
                    continue;
                }

                var fullService = "urn:schemas-upnp-org:device:MediaServer:1";

                _logger.LogInformation("Registering publisher for {ResourceName} on {DeviceAddress}", fullService, address);

                var uri = new UriBuilder(_appHost.GetApiUrlForLocalAccess(false) + descriptorUri);

                var device = new SsdpRootDevice
                {
                    CacheLifetime = TimeSpan.FromSeconds(1800), // How long SSDP clients can cache this info.
                    Location      = uri.Uri,                    // Must point to the URL that serves your devices UPnP description document.
                    Address       = address.Address,
                    PrefixLength  = address.PrefixLength,
                    FriendlyName  = "Jellyfin",
                    Manufacturer  = "Jellyfin",
                    ModelName     = "Jellyfin Server",
                    Uuid          = udn
                                    // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
                };

                SetProperies(device, fullService);
                _publisher.AddDevice(device);

                var embeddedDevices = new[]
                {
                    "urn:schemas-upnp-org:service:ContentDirectory:1",
                    "urn:schemas-upnp-org:service:ConnectionManager:1",
                    // "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1"
                };

                foreach (var subDevice in embeddedDevices)
                {
                    var embeddedDevice = new SsdpEmbeddedDevice
                    {
                        FriendlyName = device.FriendlyName,
                        Manufacturer = device.Manufacturer,
                        ModelName    = device.ModelName,
                        Uuid         = udn
                                       // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
                    };

                    SetProperies(embeddedDevice, subDevice);
                    device.AddDevice(embeddedDevice);
                }
            }
        }
예제 #14
0
파일: Program.cs 프로젝트: noex/RSSDP
		private static void PublishDevices()
		{
			if (_DevicePublisher != null)
			{
				Console.WriteLine("Stopping previous publisher.");
				_DevicePublisher.Dispose();
			}

			// Create a device publisher
			_DevicePublisher = new SsdpDevicePublisher();
			
			// Create the device(s) we want to publish.
			var rootDevice = new SsdpRootDevice()
			{
				CacheLifetime = TimeSpan.FromMinutes(30),
				FriendlyName = "Sample RSSDP Device",
				Manufacturer = "RSSDP",
				ModelNumber = "123",
				ModelName = "RSSDP Sample Device",
				SerialNumber = "123",
				Uuid = System.Guid.NewGuid().ToString()
			};

			// Now publish by adding them to the publisher.
			_DevicePublisher.AddDevice(rootDevice);

			Console.WriteLine("Publishing devices: ");
			WriteOutDevices(rootDevice);
			Console.WriteLine();
		}
예제 #15
0
파일: Startup.cs 프로젝트: cpwood/Ukor
        private void ConfigureSsdp(
            IOptions <LocalServerOptions> localServerOptions,
            SsdpLogger logger)
        {
            var device = new SsdpRootDevice()
            {
                CacheLifetime       = TimeSpan.FromHours(1),
                Location            = new Uri($"{localServerOptions.Value.RootUrl}/"),
                UrlBase             = new Uri($"{localServerOptions.Value.RootUrl}/"),
                DeviceType          = "urn:roku-com:device:player:1-0:1",
                DeviceTypeNamespace = "schemas-upnp-org",
                DeviceVersion       = 1,
                Uuid             = "29600009-5406-1005-8080-1234567890ab",
                Udn              = "uuid:29600009-5406-1005-8080-1234567890ab",
                FriendlyName     = "Ukor Server",
                Manufacturer     = "Roku",
                ManufacturerUrl  = new Uri("http://www.roku.com/"),
                ModelDescription = "Roku Streaming Player Network Media",
                ModelName        = "Ukor Server",
                ModelNumber      = "3810EU",
                ModelUrl         = new Uri("http://www.roku.com/"),
                SerialNumber     = "YH009E000001",
                Usn              = "uuid:roku:ecp:YH009E000001",
                NotificationType = "roku:ecp"
            };

            device.CustomResponseHeaders.Add(new CustomHttpHeader("Server", "Roku/9.2.0, UPnP/1.0"));
            device.CustomResponseHeaders.Add(new CustomHttpHeader("device-group.roku.com", "1E3DE502613555ACA315"));
            device.CustomResponseHeaders.Add(new CustomHttpHeader("WAKEUP", "MAC=ac:ae:01:02:03:04, Timeout=10"));

            var ecpService = new SsdpService
            {
                ServiceType          = "ecp",
                ServiceTypeNamespace = "roku-com",
                ServiceVersion       = 1,
                Uuid       = "ecp1-0",
                ScpdUrl    = new Uri("ecp_SCPD.xml", UriKind.Relative),
                ControlUrl = new Uri("roku:0")
            };

            device.AddService(ecpService);

            var dialService = new SsdpService
            {
                ServiceType          = "dial",
                ServiceTypeNamespace = "dial-multiscreen-org",
                ServiceVersion       = 1,
                Uuid       = "dial1-0",
                ScpdUrl    = new Uri("dial_SCPD.xml", UriKind.Relative),
                ControlUrl = new Uri("roku:1")
            };

            device.AddService(dialService);

            _publisher =
                new SsdpDevicePublisher {
                StandardsMode = SsdpStandardsMode.Relaxed, Log = logger
            };

            _publisher.AddDevice(device);
            _publisher.NotificationBroadcastInterval = TimeSpan.FromMinutes(10);
        }
예제 #16
0
        private async Task RegisterServerEndpoints()
        {
            if (!_config.GetDlnaConfiguration().BlastAliveMessages)
            {
                return;
            }

            var cacheLength = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds;

            _Publisher.SupportPnpRootDevice = false;

            var addresses = (await _appHost.GetLocalIpAddresses().ConfigureAwait(false)).ToList();

            foreach (var address in addresses)
            {
                //if (IPAddress.IsLoopback(address))
                //{
                //    // Should we allow this?
                //    continue;
                //}

                var addressString = address.ToString();

                var udn = (addressString).GetMD5().ToString("N");

                var services = new List <string>
                {
                    "urn:schemas-upnp-org:device:MediaServer:1",
                    "urn:schemas-upnp-org:service:ContentDirectory:1",
                    "urn:schemas-upnp-org:service:ConnectionManager:1",
                    "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1"
                };

                foreach (var fullService in services)
                {
                    _logger.Info("Registering publisher for {0} on {1}", fullService, addressString);

                    var descriptorURI = "/dlna/" + udn + "/description.xml";
                    var uri           = new Uri(_appHost.GetLocalApiUrl(address) + descriptorURI);

                    var service = fullService.Replace("urn:", string.Empty).Replace(":1", string.Empty);

                    var serviceParts = service.Split(':');

                    var deviceTypeNamespace = serviceParts[0].Replace('.', '-');

                    var device = new SsdpRootDevice
                    {
                        CacheLifetime       = TimeSpan.FromSeconds(cacheLength), //How long SSDP clients can cache this info.
                        Location            = uri,                               // Must point to the URL that serves your devices UPnP description document.
                        DeviceTypeNamespace = deviceTypeNamespace,
                        DeviceClass         = serviceParts[1],
                        DeviceType          = serviceParts[2],
                        FriendlyName        = "Emby Server",
                        Manufacturer        = "Emby",
                        ModelName           = "Emby Server",
                        Uuid = udn
                               // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
                    };

                    _Publisher.AddDevice(device);
                }
            }
        }
예제 #17
0
        private static void PublishDevices()
        {
            if (_DevicePublisher != null)
            {
                Console.WriteLine("Stopping previous publisher.");
                _DevicePublisher.Dispose();
            }

            if (_HttpServer != null)
            {
                _HttpServer.Close();
            }

            // Create a device publisher
            _DevicePublisher = new SsdpDevicePublisher();

            //These settings make RSSDP play nicely with Windows Explorer
            //and some badly behaved clients.
            _DevicePublisher.StandardsMode = SsdpStandardsMode.Relaxed;

            // Create the device(s) we want to publish.
            var url = new Uri("http://" + Environment.MachineName + ":8181/");

            var rootDevice = new SsdpRootDevice()
            {
                CacheLifetime    = TimeSpan.FromMinutes(30),
                FriendlyName     = "Sample RSSDP Device",
                Manufacturer     = "RSSDP",
                ModelNumber      = "123",
                ModelName        = "RSSDP Sample Device",
                ModelDescription = "Test Device from RSSDP Console App",
                ManufacturerUrl  = new Uri("https://github.com/Yortw/RSSDP"),
                SerialNumber     = "123",
                Uuid             = System.Guid.NewGuid().ToString(),
                UrlBase          = url
            };

            rootDevice.CustomResponseHeaders.Add(new CustomHttpHeader("X-MachineName", Environment.MachineName));

            var service = new SsdpService()
            {
                Uuid                 = System.Guid.NewGuid().ToString(),
                ServiceType          = "test-service-type",
                ServiceTypeNamespace = "rssdp-test-namespace",
                ControlUrl           = new Uri("/test/control", UriKind.Relative),
                EventSubUrl          = new Uri("/test/event", UriKind.Relative),
                ScpdUrl              = new Uri("/test", UriKind.Relative)
            };

            rootDevice.AddService(service);

            rootDevice.Location = new Uri(url, "ddd");

            //Some 3rd party tools won't show the device unless they can get
            //the device description document, so this sample uses a really simple HTTP
            //server just to serve that.
            StartHttpServerForDdd(rootDevice, url);

            // Now publish by adding them to the publisher.
            _DevicePublisher.AddDevice(rootDevice);

            Console.WriteLine("Publishing devices: ");
            WriteOutDevices(rootDevice);
            Console.WriteLine();
        }