/// <summary>
        /// Generates all URLs that are needed for the device tree(s) starting at all root devices of the specified
        /// <paramref name="server"/>.
        /// </summary>
        /// <remarks>
        /// All description-relevant information will be cleared first, if necessary.
        /// </remarks>
        /// <param name="server">UPnP server to generate URLs for.</param>
        /// <param name="config">UPnP endpoint to generate the URLs for.</param>
        public static void GenerateObjectURLs(UPnPServer server, EndpointConfiguration config)
        {
            config.RootDeviceDescriptionPaths.Clear();
            config.RootDeviceDescriptionPathsToRootDevices.Clear();
            config.ServicePaths.Clear();
            config.SCPDPathsToServices.Clear();
            config.ControlPathsToServices.Clear();
            config.EventSubPathsToServices.Clear();

            string descriptionBase = config.DescriptionPathBase;

            foreach (DvDevice rootDevice in server.RootDevices)
            {
                string path = descriptionBase + rootDevice.UDN;
                config.RootDeviceDescriptionPathsToRootDevices.Add(path, rootDevice);
                config.RootDeviceDescriptionPaths.Add(rootDevice, path);
                GeneratePathsRecursive(rootDevice, config);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Starts this UPnP server, i.e. starts a network listener and sends notifications about provided devices.
        /// </summary>
        /// <param name="advertisementInterval">Interval in seconds to repeat UPnP advertisements in the network.
        /// The UPnP architecture document (UPnP-arch-DeviceArchitecture-v1 1-20081015, 1.2.2, page 21) states a
        /// minimum of 1800 seconds. But in the world of today, that value is much to high for many applications and in many
        /// cases, a value of much less than 1800 seconds is choosen. For servers which will frequently change their
        /// availability, this value should be short, for more durable serves, this interval can be much longer (maybe a day).</param>
        public void Bind(int advertisementInterval = UPnPConsts.DEFAULT_ADVERTISEMENT_EXPIRATION_TIME)
        {
            lock (_serverData.SyncObj)
            {
                if (_serverData.IsActive)
                {
                    throw new IllegalCallException("UPnP subsystem mustn't be started multiple times");
                }

                //var port = _serverData.HTTP_PORTv4 = NetworkHelper.GetFreePort(_serverData.HTTP_PORTv4);
                var servicePrefix = "/MediaPortal/UPnPServer_" + Guid.NewGuid().GetHashCode().ToString("X");
                _serverData.ServicePrefix = servicePrefix;
                var startOptions = BuildStartOptions(servicePrefix);

                IDisposable server = null;
                try
                {
                    try
                    {
                        server = WebApp.Start(startOptions, builder => { builder.Use((context, func) => HandleHTTPRequest(context)); });
                        UPnPConfiguration.LOGGER.Info("UPnP server: HTTP listener started on addresses {0}", String.Join(", ", startOptions.Urls));
                        _serverData.HTTPListeners.Add(server);
                    }
                    catch (Exception ex)
                    {
                        if (UPnPConfiguration.IP_ADDRESS_BINDINGS?.Count > 0)
                        {
                            UPnPConfiguration.LOGGER.Warn("UPnP server: Error starting HTTP server with filters. Fallback to no filters", ex);
                        }
                        else
                        {
                            throw ex;
                        }

                        server?.Dispose();
                        startOptions = UPnPServer.BuildStartOptions(servicePrefix, new List <string>());
                        server       = WebApp.Start(startOptions, builder => { builder.Use((context, func) => HandleHTTPRequest(context)); });
                        UPnPConfiguration.LOGGER.Info("UPnP server: HTTP listener started on addresses {0}", String.Join(", ", startOptions.Urls));
                        _serverData.HTTPListeners.Add(server);
                    }
                }
                catch (SocketException e)
                {
                    server?.Dispose();
                    UPnPConfiguration.LOGGER.Warn("UPnPServer: Error starting HTTP server", e);
                }

                _serverData.SSDPController = new SSDPServerController(_serverData)
                {
                    AdvertisementExpirationTime = advertisementInterval
                };
                _serverData.GENAController = new GENAServerController(_serverData);

                InitializeDiscoveryEndpoints();

                NetworkChange.NetworkAddressChanged += OnNetworkAddressChanged;
                _serverData.IsActive = true;

                // At the end, start the controllers
                _serverData.SSDPController.Start();
                _serverData.GENAController.Start();
                UPnPConfiguration.LOGGER.Info("UPnP server online hosting {0} UPnP root devices", _serverData.Server.RootDevices.Count);
            }
        }
 public UPnPSystemResumeHelper(UPnPServer upnpServer)
 {
   _upnpServer = upnpServer;
   _messageQueue = new AsynchronousMessageQueue(this, new[] { SystemMessaging.CHANNEL });
   _messageQueue.PreviewMessage += OnMessageReceived;
 }