Example #1
0
        public void Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint)
        {
            // No matter what, this method should never throw an exception. If something goes wrong
            // we should still be in a position to handle the next reply correctly.
            try
            {
                /* For UPnP Port Mapping we need ot find either WANPPPConnection or WANIPConnection.
                 *               Any other device type is no good to us for this purpose. See the IGP overview paper
                 *               page 5 for an overview of device types and their hierarchy.
                 *               http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf */

                /* TODO: Currently we are assuming version 1 of the protocol. We should figure out which
                 *               version it is and apply the correct URN. */

                /* Some routers don't correctly implement the version ID on the URN, so we only search for the type
                 *               prefix. */

                // We have an internet gateway device now
                UpnpNatDevice d = new UpnpNatDevice(localAddress, deviceInfo, endpoint, string.Empty, _logger, _httpClient);

                NatUtility.Log("Fetching service list: {0}", d.HostEndPoint);
                OnDeviceFound(new DeviceEventArgs(d));
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error decoding device response", ex);
            }
        }
Example #2
0
        public async Task Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint)
        {
            if (localAddress == null)
            {
                throw new ArgumentNullException("localAddress");
            }

            try
            {
                /* For UPnP Port Mapping we need ot find either WANPPPConnection or WANIPConnection.
                 *               Any other device type is no good to us for this purpose. See the IGP overview paper
                 *               page 5 for an overview of device types and their hierarchy.
                 *               http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf */

                /* TODO: Currently we are assuming version 1 of the protocol. We should figure out which
                 *               version it is and apply the correct URN. */

                /* Some routers don't correctly implement the version ID on the URN, so we only search for the type
                 *               prefix. */

                // We have an internet gateway device now
                UpnpNatDevice d = new UpnpNatDevice(localAddress, deviceInfo, endpoint, string.Empty, _logger, _httpClient);

                await d.GetServicesList().ConfigureAwait(false);

                OnDeviceFound(new DeviceEventArgs(d));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error decoding device response");
            }
        }
        internal UpnpNatDevice(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint hostEndPoint, string serviceType)
        {
            this.LastSeen     = DateTime.Now;
            this.localAddress = localAddress;

            // Split the string at the "location" section so i can extract the ipaddress and service description url
            string locationDetails = deviceInfo.Location.ToString();

            this.serviceType = serviceType;

            // Make sure we have no excess whitespace
            locationDetails = locationDetails.Trim();

            // FIXME: Is this reliable enough. What if we get a hostname as opposed to a proper http address
            // Are we going to get addresses with the "http://" attached?
            if (locationDetails.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase))
            {
                NatUtility.Log("Found device at: {0}", locationDetails);
                // This bit strings out the "http://" from the string
                locationDetails = locationDetails.Substring(7);

                this.hostEndPoint = hostEndPoint;

                NatUtility.Log("Parsed device as: {0}", this.hostEndPoint.ToString());

                // The service description URL is the remainder of the "locationDetails" string. The bit that was originally after the ip
                // and port information
                this.serviceDescriptionUrl = locationDetails.Substring(locationDetails.IndexOf('/'));
            }
            else
            {
                NatUtility.Log("Couldn't decode address. Please send following string to the developer: ");
            }
        }
        public void Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint)
        {
            // No matter what, this method should never throw an exception. If something goes wrong
            // we should still be in a position to handle the next reply correctly.
            try
            {
                /* For UPnP Port Mapping we need ot find either WANPPPConnection or WANIPConnection.
                 *               Any other device type is no good to us for this purpose. See the IGP overview paper
                 *               page 5 for an overview of device types and their hierarchy.
                 *               http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf */

                /* TODO: Currently we are assuming version 1 of the protocol. We should figure out which
                 *               version it is and apply the correct URN. */

                /* Some routers don't correctly implement the version ID on the URN, so we only search for the type
                 *               prefix. */

                // We have an internet gateway device now
                UpnpNatDevice d = new UpnpNatDevice(localAddress, deviceInfo, endpoint, string.Empty);

                if (devices.Contains(d))
                {
                    // We already have found this device, so we just refresh it to let people know it's
                    // Still alive. If a device doesn't respond to a search, we dump it.
                    devices[devices.IndexOf(d)].LastSeen = DateTime.Now;
                }
                else
                {
                    // If we send 3 requests at a time, ensure we only fetch the services list once
                    // even if three responses are received
                    if (lastFetched.ContainsKey(endpoint.Address))
                    {
                        DateTime last = lastFetched[endpoint.Address];
                        if ((DateTime.Now - last) < TimeSpan.FromSeconds(20))
                        {
                            return;
                        }
                    }
                    lastFetched[endpoint.Address] = DateTime.Now;

                    // Once we've parsed the information we need, we tell the device to retrieve it's service list
                    // Once we successfully receive the service list, the callback provided will be invoked.
                    NatUtility.Log("Fetching service list: {0}", d.HostEndPoint);
                    d.GetServicesList(DeviceSetupComplete);
                }
            }
            catch (Exception ex)
            {
                NatUtility.Log("Unhandled exception when trying to decode a device's response Send me the following data: ");
                NatUtility.Log("ErrorMessage:");
                NatUtility.Log(ex.Message);
            }
        }
        public static void Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint, NatProtocol protocol)
        {
            switch (protocol)
            {
            case NatProtocol.Upnp:
                UpnpSearcher.Instance.Handle(localAddress, deviceInfo, endpoint);
                break;

            default:
                throw new ArgumentException("Unexpected protocol: " + protocol);
            }
        }
Example #6
0
        public Task Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint, NatProtocol protocol)
        {
            switch (protocol)
            {
            case NatProtocol.Upnp:
                var searcher = new UpnpSearcher(Logger, HttpClient);
                searcher.DeviceFound += Searcher_DeviceFound;
                return(searcher.Handle(localAddress, deviceInfo, endpoint));

            default:
                throw new ArgumentException("Unexpected protocol: " + protocol);
            }
        }
Example #7
0
        public static async Task Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint, NatProtocol protocol)
        {
            switch (protocol)
            {
            case NatProtocol.Upnp:
                var searcher = new UpnpSearcher(Logger, HttpClient);
                searcher.DeviceFound += Searcher_DeviceFound;
                await searcher.Handle(localAddress, deviceInfo, endpoint).ConfigureAwait(false);

                break;

            default:
                throw new ArgumentException("Unexpected protocol: " + protocol);
            }
        }
Example #8
0
        private async Task AddDevice(UpnpDeviceInfo info, string location, CancellationToken cancellationToken)
        {
            var uri = info.Location;

            _logger.LogDebug("Attempting to create PlayToController from location {0}", location);

            _logger.LogDebug("Logging session activity from location {0}", location);
            if (info.Headers.TryGetValue("USN", out string uuid))
            {
                uuid = GetUuid(uuid);
            }
            else
            {
                uuid = location.GetMD5().ToString("N", CultureInfo.InvariantCulture);
            }

            var sessionInfo = _sessionManager.LogSessionActivity("DLNA", _appHost.ApplicationVersionString, uuid, null, uri.OriginalString, null);

            var controller = sessionInfo.SessionControllers.OfType <PlayToController>().FirstOrDefault();

            if (controller == null)
            {
                var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _logger, cancellationToken).ConfigureAwait(false);

                string deviceName = device.Properties.Name;

                _sessionManager.UpdateDeviceName(sessionInfo.Id, deviceName);

                string serverAddress;
                if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IPAddress.Any) || info.LocalIpAddress.Equals(IPAddress.IPv6Any))
                {
                    serverAddress = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    serverAddress = _appHost.GetLocalApiUrl(info.LocalIpAddress);
                }

                controller = new PlayToController(
                    sessionInfo,
                    _sessionManager,
                    _libraryManager,
                    _logger,
                    _dlnaManager,
                    _userManager,
                    _imageProcessor,
                    serverAddress,
                    null,
                    _deviceDiscovery,
                    _userDataManager,
                    _localization,
                    _mediaSourceManager,
                    _config,
                    _mediaEncoder);

                sessionInfo.AddController(controller);

                controller.Init(device);

                var profile = _dlnaManager.GetProfile(device.Properties.ToDeviceIdentification()) ??
                              _dlnaManager.GetDefaultProfile();

                _sessionManager.ReportCapabilities(sessionInfo.Id, new ClientCapabilities
                {
                    PlayableMediaTypes = profile.GetSupportedMediaTypes(),

                    SupportedCommands = new[]
                    {
                        GeneralCommandType.VolumeDown.ToString(),
                        GeneralCommandType.VolumeUp.ToString(),
                        GeneralCommandType.Mute.ToString(),
                        GeneralCommandType.Unmute.ToString(),
                        GeneralCommandType.ToggleMute.ToString(),
                        GeneralCommandType.SetVolume.ToString(),
                        GeneralCommandType.SetAudioStreamIndex.ToString(),
                        GeneralCommandType.SetSubtitleStreamIndex.ToString(),
                        GeneralCommandType.PlayMediaSource.ToString()
                    },

                    SupportsMediaControl = true
                });

                _logger.LogInformation("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName);
            }
        }
Example #9
0
        private async Task AddDevice(UpnpDeviceInfo info, string location, CancellationToken cancellationToken)
        {
            var uri = info.Location;

            _logger.Debug("Attempting to create PlayToController from location {0}", location);
            var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger, _timerFactory, cancellationToken).ConfigureAwait(false);

            _logger.Debug("Logging session activity from location {0}", location);
            var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null).ConfigureAwait(false);

            var controller = sessionInfo.SessionController as PlayToController;

            if (controller == null)
            {
                string serverAddress;
                if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IpAddressInfo.Any) || info.LocalIpAddress.Equals(IpAddressInfo.IPv6Any))
                {
                    serverAddress = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    serverAddress = _appHost.GetLocalApiUrl(info.LocalIpAddress);
                }

                string accessToken = null;

                sessionInfo.SessionController = controller = new PlayToController(sessionInfo,
                                                                                  _sessionManager,
                                                                                  _libraryManager,
                                                                                  _logger,
                                                                                  _dlnaManager,
                                                                                  _userManager,
                                                                                  _imageProcessor,
                                                                                  serverAddress,
                                                                                  accessToken,
                                                                                  _deviceDiscovery,
                                                                                  _userDataManager,
                                                                                  _localization,
                                                                                  _mediaSourceManager,
                                                                                  _config,
                                                                                  _mediaEncoder);

                controller.Init(device);

                var profile = _dlnaManager.GetProfile(device.Properties.ToDeviceIdentification()) ??
                              _dlnaManager.GetDefaultProfile();

                _sessionManager.ReportCapabilities(sessionInfo.Id, new ClientCapabilities
                {
                    PlayableMediaTypes = profile.GetSupportedMediaTypes(),

                    SupportedCommands = new string[]
                    {
                        GeneralCommandType.VolumeDown.ToString(),
                        GeneralCommandType.VolumeUp.ToString(),
                        GeneralCommandType.Mute.ToString(),
                        GeneralCommandType.Unmute.ToString(),
                        GeneralCommandType.ToggleMute.ToString(),
                        GeneralCommandType.SetVolume.ToString(),
                        GeneralCommandType.SetAudioStreamIndex.ToString(),
                        GeneralCommandType.SetSubtitleStreamIndex.ToString()
                    },

                    SupportsMediaControl = true,

                    // xbox one creates a new uuid everytime it restarts
                    SupportsPersistentIdentifier = (device.Properties.ModelName ?? string.Empty).IndexOf("xbox", StringComparison.OrdinalIgnoreCase) == -1
                });

                _logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName);
            }
        }