/// <summary> /// Stops this UPnP network tracker's activity, i.e. closes the UPnP network listener and clears all /// <see cref="KnownRootDevices"/>. /// </summary> public void Close() { lock (_cpData.SyncObj) { if (!_active) { return; } _active = false; foreach (RootEntry entry in _cpData.SSDPController.RootEntries) { RootDescriptor rd = GetRootDescriptor(entry); if (rd == null) { continue; } InvalidateDescriptor(rd); } SSDPClientController ssdpController = _cpData.SSDPController; ssdpController.Close(); ssdpController.RootDeviceAdded -= OnSSDPRootDeviceAdded; ssdpController.RootDeviceRemoved -= OnSSDPRootDeviceRemoved; ssdpController.DeviceRebooted -= OnSSDPDeviceRebooted; ssdpController.DeviceConfigurationChanged -= OnSSDPDeviceConfigurationChanged; _cpData.SSDPController = null; foreach (DescriptionRequestState state in _pendingRequests) { state.Request.Abort(); } _pendingRequests.Clear(); } }
private void OnServiceDescriptionReceived(IAsyncResult asyncResult) { DescriptionRequestState state = (DescriptionRequestState)asyncResult.AsyncState; RootDescriptor rd = state.RootDescriptor; HttpWebRequest request = state.Request; try { using (WebResponse response = request.EndGetResponse(asyncResult)) { using (_cpData.Lock.EnterRead()) if (rd.State != RootDescriptorState.AwaitingServiceDescriptions) { return; } try { using (Stream body = CompressionHelper.Decompress(response)) { XPathDocument xmlServiceDescription = new XPathDocument(body); state.CurrentServiceDescriptor.ServiceDescription = xmlServiceDescription; state.CurrentServiceDescriptor.State = ServiceDescriptorState.Ready; } } catch (Exception) // Don't log exceptions at this low protocol level { using (_cpData.Lock.EnterWrite()) { state.CurrentServiceDescriptor.State = ServiceDescriptorState.Erroneous; rd.State = RootDescriptorState.Erroneous; } } finally { response.Close(); } } } catch (WebException e) { state.CurrentServiceDescriptor.State = ServiceDescriptorState.Erroneous; using (_cpData.Lock.EnterWrite()) rd.State = RootDescriptorState.Erroneous; if (e.Response != null) { e.Response.Close(); } } // Don't hold the lock while calling ContinueGetServiceDescription - that method is calling event handlers try { ContinueGetServiceDescription(state); } catch (Exception) // Don't log exceptions at this low protocol level { using (_cpData.Lock.EnterWrite()) rd.State = RootDescriptorState.Erroneous; } }
protected void InitializeRootDescriptor(RootEntry rootEntry) { RootDescriptor rd = new RootDescriptor(rootEntry) { State = RootDescriptorState.AwaitingDeviceDescription }; lock (_cpData.SyncObj) SetRootDescriptor(rootEntry, rd); try { LinkData preferredLink = rootEntry.PreferredLink; HttpWebRequest request = CreateHttpGetRequest(new Uri(preferredLink.DescriptionLocation), preferredLink.Endpoint.EndPointIPAddress); DescriptionRequestState state = new DescriptionRequestState(rd, request); lock (_cpData.SyncObj) _pendingRequests.Add(state); IAsyncResult result = request.BeginGetResponse(OnDeviceDescriptionReceived, state); NetworkHelper.AddTimeout(request, result, PENDING_REQUEST_TIMEOUT * 1000); } catch (Exception) // Don't log messages at this low protocol level { lock (_cpData.SyncObj) rd.State = RootDescriptorState.Erroneous; } }
private void HandleDeviceConfigurationChanged(RootDescriptor rootDescriptor) { // Configuration changes cannot be given to our clients because they need a re-initialization of the // device and all service description documents. So configuration changes will be handled by invocing a // root device remove/add event combination. The add event will be fired when the initialization of the root descriptor has finished. InvokeRootDeviceRemoved(rootDescriptor); InitializeRootDescriptor(rootDescriptor.SSDPRootEntry); }
protected DeviceConnection DoConnect(RootDescriptor descriptor, string deviceUuid, DataTypeResolverDlgt dataTypeResolver, bool useHttpKeepAlive = true) { lock (_cpData.SyncObj) { DeviceConnection connection = new DeviceConnection(this, descriptor, deviceUuid, _cpData, dataTypeResolver, useHttpKeepAlive); _connectedDevices.Add(deviceUuid, connection); return(connection); } }
public static ServerDescriptor GetMPBackendServerDescriptor(RootDescriptor uPnPRootDescriptor) { DeviceDescriptor rootDescriptor = DeviceDescriptor.CreateRootDeviceDescriptor(uPnPRootDescriptor); if (rootDescriptor == null) return null; DeviceDescriptor serverDeviceDescriptor = rootDescriptor.FindFirstDevice( UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE_VERSION); return serverDeviceDescriptor == null ? null : new ServerDescriptor(serverDeviceDescriptor); }
private void OnSSDPDeviceConfigurationChanged(RootEntry rootEntry) { RootDescriptor rd = GetRootDescriptor(rootEntry); if (rd == null) { return; } HandleDeviceConfigurationChanged(rd); }
private void OnDeviceRebooted(RootDescriptor rootdescriptor) { foreach (DeviceConnection connection in _connectedDevices.Values) { if (connection.RootDescriptor == rootdescriptor) { connection.OnDeviceRebooted(); } } }
protected void InvalidateDescriptor(RootDescriptor rd) { rd.State = RootDescriptorState.Invalid; foreach (IDictionary <string, ServiceDescriptor> sdDict in rd.ServiceDescriptors.Values) { foreach (ServiceDescriptor sd in sdDict.Values) { sd.State = ServiceDescriptorState.Invalid; } } }
/// <summary> /// Creates a new <see cref="DeviceConnection"/> to the UPnP device contained in the given /// <paramref name="rootDescriptor"/> with the given <paramref name="deviceUuid"/>. /// </summary> /// <param name="controlPoint">Control point hosting the new device connection instance.</param> /// <param name="rootDescriptor">Root descriptor containing the description of the UPnP device to connect.</param> /// <param name="deviceUuid">UUID of the UPnP device to connect.</param> /// <param name="cpData">Shared control point data structure.</param> /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param> public DeviceConnection(UPnPControlPoint controlPoint, RootDescriptor rootDescriptor, string deviceUuid, CPData cpData, DataTypeResolverDlgt dataTypeResolver) { _controlPoint = controlPoint; _cpData = cpData; _rootDescriptor = rootDescriptor; _deviceUUID = deviceUuid; _genaClientController = new GENAClientController(_cpData, this, rootDescriptor.SSDPRootEntry.PreferredLink.Endpoint, rootDescriptor.SSDPRootEntry.UPnPVersion); BuildDeviceProxy(rootDescriptor, deviceUuid, dataTypeResolver); _genaClientController.Start(); }
/// <summary> /// Establishes the actual device connection by building the control point's proxy device tree corresponding to the /// device contained in the given <paramref name="rootDescriptor"/> specified by its <paramref name="deviceUUID"/>. /// </summary> /// <param name="rootDescriptor">Root descriptor which contains the device to build.</param> /// <param name="deviceUUID">UUID of the device to connect.</param> /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param> private void BuildDeviceProxy(RootDescriptor rootDescriptor, string deviceUUID, DataTypeResolverDlgt dataTypeResolver) { if (rootDescriptor.State != RootDescriptorState.Ready) { throw new ArgumentException("Root descriptor is not ready - cannot connect"); } DeviceDescriptor rootDeviceDescriptor = DeviceDescriptor.CreateRootDeviceDescriptor(rootDescriptor); DeviceDescriptor deviceDescriptor = rootDeviceDescriptor.FindDevice(deviceUUID); _device = CpDevice.ConnectDevice(this, deviceDescriptor, dataTypeResolver); }
private void OnSSDPRootDeviceRemoved(RootEntry rootEntry) { RootDescriptor rd = GetRootDescriptor(rootEntry); if (rd == null) { return; } lock (_cpData.SyncObj) InvalidateDescriptor(rd); InvokeRootDeviceRemoved(rd); }
private void OnSSDPRootDeviceRemoved(RootEntry rootEntry) { RootDescriptor rd = GetRootDescriptor(rootEntry); if (rd == null) { return; } using (_cpData.Lock.EnterWrite()) InvalidateDescriptor(rd); InvokeRootDeviceRemoved(rd); }
private void OnDeviceDescriptionReceived(IAsyncResult asyncResult) { DescriptionRequestState state = (DescriptionRequestState)asyncResult.AsyncState; RootDescriptor rd = state.RootDescriptor; HttpWebRequest request = state.Request; try { WebResponse response = request.EndGetResponse(asyncResult); if (rd.State != RootDescriptorState.AwaitingDeviceDescription) { return; } try { using (Stream body = CompressionHelper.Decompress(response)) { XPathDocument xmlDeviceDescription = new XPathDocument(body); lock (_cpData.SyncObj) { rd.DeviceDescription = xmlDeviceDescription; DeviceDescriptor rootDeviceDescriptor = DeviceDescriptor.CreateRootDeviceDescriptor(rd); if (rootDeviceDescriptor == null) { // No root device description available rd.State = RootDescriptorState.Erroneous; return; } ExtractServiceDescriptorsRecursive(rootDeviceDescriptor, rd.ServiceDescriptors, state.PendingServiceDescriptions); rd.State = RootDescriptorState.AwaitingServiceDescriptions; } } ContinueGetServiceDescription(state); } catch (Exception) // Don't log exceptions at this low protocol level { rd.State = RootDescriptorState.Erroneous; } finally { response.Close(); } } catch (WebException e) { rd.State = RootDescriptorState.Erroneous; if (e.Response != null) { e.Response.Close(); } } }
protected void InvokeDeviceRebooted(RootDescriptor rd) { try { DeviceRebootedDlgt dlgt = DeviceRebooted; if (dlgt != null) { dlgt(rd); } } catch (Exception e) { UPnPConfiguration.LOGGER.Warn("UPnPNetworkTracker: Error invoking DeviceRebooted delegate", e); } }
private void ContinueGetServiceDescription(DescriptionRequestState state) { RootDescriptor rootDescriptor = state.RootDescriptor; IEnumerator <ServiceDescriptor> enumer = state.PendingServiceDescriptions.GetEnumerator(); if (!enumer.MoveNext()) { using (_cpData.Lock.EnterWrite()) { if (rootDescriptor.State != RootDescriptorState.AwaitingServiceDescriptions) { return; } _pendingRequests.Remove(state); rootDescriptor.State = RootDescriptorState.Ready; } // This event is needed for two cases: 1) "Normal" first device advertisement, 2) configuration change event (see comment in method HandleDeviceConfigurationChanged) InvokeRootDeviceAdded(rootDescriptor); } else { using (_cpData.Lock.EnterRead()) if (rootDescriptor.State != RootDescriptorState.AwaitingServiceDescriptions) { return; } state.CurrentServiceDescriptor = enumer.Current; string url = state.CurrentServiceDescriptor.DescriptionURL; state.PendingServiceDescriptions.Remove(state.CurrentServiceDescriptor); state.CurrentServiceDescriptor.State = ServiceDescriptorState.AwaitingDescription; try { LinkData preferredLink = rootDescriptor.SSDPRootEntry.PreferredLink; HttpWebRequest request = CreateHttpGetRequest(new Uri(new Uri(preferredLink.DescriptionLocation), url), preferredLink.Endpoint.EndPointIPAddress); state.Request = request; IAsyncResult result = request.BeginGetResponse(OnServiceDescriptionReceived, state); NetworkHelper.AddTimeout(request, result, PENDING_REQUEST_TIMEOUT * 1000); } catch (Exception) // Don't log exceptions at this low protocol level { using (_cpData.Lock.EnterWrite()) state.CurrentServiceDescriptor.State = ServiceDescriptorState.Erroneous; } } }
void OnUPnPRootDeviceAdded(RootDescriptor rootDescriptor) { ICollection<ServerDescriptor> availableServers; lock (_networkTracker.SharedControlPointData.SyncObj) { ServerDescriptor serverDescriptor = ServerDescriptor.GetMPBackendServerDescriptor(rootDescriptor); if (serverDescriptor == null || _availableServers.Contains(serverDescriptor)) return; SystemName preferredLink = serverDescriptor.GetPreferredLink(); ServiceRegistration.Get<ILogger>().Debug("UPnPServerWatcher: Found MediaPortal 2 BackendServer '{0}' at host '{1}' (IP address: '{2}')", serverDescriptor.ServerName, preferredLink.HostName, preferredLink.Address); _availableServers.Add(serverDescriptor); availableServers = _availableServers; } InvokeAvailableBackendServersChanged(availableServers, true); }
private void OnSSDPDeviceRebooted(RootEntry rootEntry, bool configurationChanged) { RootDescriptor rd = GetRootDescriptor(rootEntry); if (rd == null) { return; } if (configurationChanged) { HandleDeviceConfigurationChanged(rd); } else { InvokeDeviceRebooted(rd); } }
protected IResourceInformationService TryGetResourceInformationService(RootDescriptor rootDescriptor) { DeviceConnection connection; lock (_networkTracker.SharedControlPointData.SyncObj) { object service; if (rootDescriptor.SSDPRootEntry.ClientProperties.TryGetValue(KEY_RESOURCE_INFORMATION_SERVICE, out service)) return service as IResourceInformationService; } DeviceDescriptor rootDevice = DeviceDescriptor.CreateRootDeviceDescriptor(rootDescriptor); DeviceDescriptor frontendServerDevice = rootDevice.FindFirstDevice( UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE_VERSION) ?? rootDevice.FindFirstDevice(UPnPTypesAndIds.FRONTEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.FRONTEND_SERVER_DEVICE_TYPE_VERSION); if (frontendServerDevice == null) return null; string deviceUuid = frontendServerDevice.DeviceUUID; try { connection = _controlPoint.Connect(rootDescriptor, deviceUuid, UPnPExtendedDataTypes.ResolveDataType); } catch (Exception e) { ServiceRegistration.Get<ILogger>().Warn("Error connecting to UPnP MP2 device '{0}'", e, deviceUuid); return null; } try { CpService rasStub = connection.Device.FindServiceByServiceId(UPnPTypesAndIds.RESOURCE_INFORMATION_SERVICE_ID); if (rasStub == null) throw new InvalidDataException("ResourceAccess service not found in device '{0}'", deviceUuid); IResourceInformationService ris = new UPnPResourceInformationServiceProxy(rasStub); lock (_networkTracker.SharedControlPointData.SyncObj) rootDescriptor.SSDPRootEntry.ClientProperties[KEY_RESOURCE_INFORMATION_SERVICE] = ris; return ris; } catch (Exception e) { ServiceRegistration.Get<ILogger>().Warn("Error connecting to services of UPnP MP2 device '{0}'", e, deviceUuid); _controlPoint.Disconnect(deviceUuid); return null; } }
/// <summary> /// Connects to the device of the given <paramref name="deviceUuid"/> specified in the <paramref name="rootDescriptor"/>. /// </summary> /// <param name="rootDescriptor">UPnP root descriptor to connect.</param> /// <param name="deviceUuid">UUID of the device in the root descriptor which is the node to connect.</param> /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param> /// <param name="useHttpKeepAlive"><c>True</c> to set the HTTP keep-alive header in action requests sent over the connection, otherwise <c>false</c>.</param> /// <exception cref="ArgumentException"> /// <list type="bullet"> /// <item>If the device with the specified <paramref name="deviceUuid"/> isn't present /// in the given <paramref name="rootDescriptor"/></item> /// <item>If the given <paramref name="rootDescriptor"/> has is in an erroneous state /// (<c><see cref="RootDescriptor.State"/> == <see cref="RootDescriptorState.Erroneous"/></c>)</item> /// <item>If the given <paramref name="rootDescriptor"/> contains erroneous data, e.g. erroneous device or /// service descriptions</item> /// </list> /// </exception> public DeviceConnection Connect(RootDescriptor rootDescriptor, string deviceUuid, DataTypeResolverDlgt dataTypeResolver, bool useHttpKeepAlive = true) { return DoConnect(rootDescriptor, deviceUuid, dataTypeResolver, useHttpKeepAlive); }
protected DeviceConnection DoConnect(RootDescriptor descriptor, string deviceUuid, DataTypeResolverDlgt dataTypeResolver, bool useHttpKeepAlive = true) { lock (_cpData.SyncObj) { DeviceConnection connection = new DeviceConnection(this, descriptor, deviceUuid, _cpData, dataTypeResolver, useHttpKeepAlive); _connectedDevices.Add(deviceUuid, connection); return connection; } }
private void OnDeviceRebooted(RootDescriptor rootdescriptor) { foreach (DeviceConnection connection in _connectedDevices.Values) if (connection.RootDescriptor == rootdescriptor) connection.OnDeviceRebooted(); }
private void OnRootDeviceRemoved(RootDescriptor rootdescriptor) { DoDisconnect(rootdescriptor.SSDPRootEntry.RootDeviceUUID, false); }
void OnUPnPRootDeviceRemoved(RootDescriptor rootDescriptor) { ClientDescriptor clientDescriptor; lock (_networkTracker.SharedControlPointData.SyncObj) { clientDescriptor = ClientDescriptor.GetMPFrontendServerDescriptor(rootDescriptor); if (clientDescriptor == null || !_availableClients.Contains(clientDescriptor)) return; ServiceRegistration.Get<ILogger>().Debug("UPnPServerControlPoint: MP2 client '{0}' (system ID '{1}') at host '{2}' was removed from the network", clientDescriptor.ClientName, clientDescriptor.MPFrontendServerUUID, clientDescriptor.System.HostName); _availableClients.Remove(clientDescriptor); } InvokeClientUnavailable(clientDescriptor); // The client connection has its own event handler for disconnects - it will trigger method OnClientDisconnected // as result of disconnection, this will remove the client connection from the _clientConnections collection }
private void OnUpnpRootDeviceRemoved(RootDescriptor rootDescriptor) { if (rootDescriptor == null) { return; } _knownUpnpDevices.Remove(rootDescriptor.SSDPRootEntry.RootDeviceUUID); DeviceDescriptor deviceDescriptor = DeviceDescriptor.CreateRootDeviceDescriptor(rootDescriptor); IEnumerator<DeviceEntry> childDeviceEn = rootDescriptor.SSDPRootEntry.Devices.Values.GetEnumerator(); bool isFirst = true; while (childDeviceEn.MoveNext()) { foreach (string serviceUrn in childDeviceEn.Current.Services) { if (serviceUrn.Equals("urn:schemas-opencable-com:service:Tuner:1")) { if (isFirst) { isFirst = false; Log.Log.Info("UPnP device {0} removed", deviceDescriptor.FriendlyName); } IEnumerator<DeviceDescriptor> childDeviceDescriptorEn = deviceDescriptor.ChildDevices.GetEnumerator(); while (childDeviceDescriptorEn.MoveNext()) { if (childDeviceDescriptorEn.Current.DeviceUUID == childDeviceEn.Current.UUID) { break; } } Log.Log.Info(" remove {0} {1}", childDeviceDescriptorEn.Current.FriendlyName, childDeviceDescriptorEn.Current.DeviceUDN); _deviceEventListener.OnDeviceRemoved(childDeviceDescriptorEn.Current.DeviceUDN); break; } } } }
private void networkTracker_RootDeviceRemoved(RootDescriptor rootdescriptor) { ExecuteInUIThread(UpdateTreeView); }
private void OnRootDeviceRemoved(RootDescriptor rootdescriptor) { DoDisconnect(rootdescriptor.SSDPRootEntry.RootDeviceUUID, false); }
/// <summary> /// Creates a new <see cref="DeviceConnection"/> to the UPnP device contained in the given /// <paramref name="rootDescriptor"/> with the given <paramref name="deviceUuid"/>. /// </summary> /// <param name="controlPoint">Control point hosting the new device connection instance.</param> /// <param name="rootDescriptor">Root descriptor containing the description of the UPnP device to connect.</param> /// <param name="deviceUuid">UUID of the UPnP device to connect.</param> /// <param name="cpData">Shared control point data structure.</param> /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param> /// <param name="useHttpKeepAlive"><c>True</c> to set the HTTP keep-alive header in action requests sent over the connection, otherwise <c>false</c>.</param> public DeviceConnection(UPnPControlPoint controlPoint, RootDescriptor rootDescriptor, string deviceUuid, CPData cpData, DataTypeResolverDlgt dataTypeResolver, bool useHttpKeepAlive = true) { _controlPoint = controlPoint; _cpData = cpData; _rootDescriptor = rootDescriptor; _deviceUUID = deviceUuid; _useHttpKeepAlive = useHttpKeepAlive; _genaClientController = new GENAClientController(_cpData, this, rootDescriptor.SSDPRootEntry.PreferredLink.Endpoint, rootDescriptor.SSDPRootEntry.UPnPVersion); BuildDeviceProxy(rootDescriptor, deviceUuid, dataTypeResolver); _genaClientController.Start(); }
void OnUPnPRootDeviceAdded(RootDescriptor rootDescriptor) { TryConnect(rootDescriptor); }
protected void SetRootDescriptor(RootEntry rootEntry, RootDescriptor rootDescriptor) { rootEntry.ClientProperties[KEY_ROOT_DESCRIPTOR] = rootDescriptor; }
/// <summary> /// Connects to the device of the given <paramref name="deviceUuid"/> specified in the <paramref name="rootDescriptor"/>. /// </summary> /// <param name="rootDescriptor">UPnP root descriptor to connect.</param> /// <param name="deviceUuid">UUID of the device in the root descriptor which is the node to connect.</param> /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param> /// <param name="useHttpKeepAlive"><c>True</c> to set the HTTP keep-alive header in action requests sent over the connection, otherwise <c>false</c>.</param> /// <exception cref="ArgumentException"> /// <list type="bullet"> /// <item>If the device with the specified <paramref name="deviceUuid"/> isn't present /// in the given <paramref name="rootDescriptor"/></item> /// <item>If the given <paramref name="rootDescriptor"/> has is in an erroneous state /// (<c><see cref="RootDescriptor.State"/> == <see cref="RootDescriptorState.Erroneous"/></c>)</item> /// <item>If the given <paramref name="rootDescriptor"/> contains erroneous data, e.g. erroneous device or /// service descriptions</item> /// </list> /// </exception> public DeviceConnection Connect(RootDescriptor rootDescriptor, string deviceUuid, DataTypeResolverDlgt dataTypeResolver, bool useHttpKeepAlive = true) { return(DoConnect(rootDescriptor, deviceUuid, dataTypeResolver, useHttpKeepAlive)); }
public DescriptionRequestState(RootDescriptor rootDescriptor, HttpWebRequest httpWebRequest) { _rootDescriptor = rootDescriptor; _httpWebRequest = httpWebRequest; }
private void OnUpnpRootDeviceAdded(RootDescriptor rootDescriptor) { if (rootDescriptor == null || rootDescriptor.State != RootDescriptorState.Ready || _knownUpnpDevices.Contains(rootDescriptor.SSDPRootEntry.RootDeviceUUID)) { return; } _knownUpnpDevices.Add(rootDescriptor.SSDPRootEntry.RootDeviceUUID); DeviceDescriptor deviceDescriptor = DeviceDescriptor.CreateRootDeviceDescriptor(rootDescriptor); IEnumerator<DeviceEntry> childDeviceEn = rootDescriptor.SSDPRootEntry.Devices.Values.GetEnumerator(); bool isFirst = true; while (childDeviceEn.MoveNext()) { foreach (string serviceUrn in childDeviceEn.Current.Services) { // Supported device? if (serviceUrn.Equals("urn:schemas-opencable-com:service:Tuner:1")) { if (isFirst) { isFirst = false; Log.Log.Info("Detected new OCUR/DRI device {0}", deviceDescriptor.FriendlyName); } // Find the corresponding DeviceDescriptor. IEnumerator<DeviceDescriptor> childDeviceDescriptorEn = deviceDescriptor.ChildDevices.GetEnumerator(); while (childDeviceDescriptorEn.MoveNext()) { if (childDeviceDescriptorEn.Current.DeviceUUID == childDeviceEn.Current.UUID) { break; } } Log.Log.Info(" add {0} {1}", childDeviceDescriptorEn.Current.FriendlyName, childDeviceDescriptorEn.Current.DeviceUDN); _deviceEventListener.OnDeviceAdded(new TunerDri(childDeviceDescriptorEn.Current, _upnpControlPoint)); break; } } } }
/// <summary> /// Connects to the device of the given <paramref name="deviceUuid"/> specified in the <paramref name="rootDescriptor"/>. /// </summary> /// <param name="rootDescriptor">UPnP root descriptor to connect.</param> /// <param name="deviceUuid">UUID of the device in the root descriptor which is the node to connect.</param> /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param> /// <exception cref="ArgumentException"> /// <list type="bullet"> /// <item>If the device with the specified <paramref name="deviceUuid"/> isn't present /// in the given <paramref name="rootDescriptor"/></item> /// <item>If the given <paramref name="rootDescriptor"/> has is in an erroneous state /// (<c><see cref="RootDescriptor.State"/> == <see cref="RootDescriptorState.Erroneous"/></c>)</item> /// <item>If the given <paramref name="rootDescriptor"/> contains erroneous data, e.g. erroneous device or /// service descriptions</item> /// </list> /// </exception> public DeviceConnection Connect(RootDescriptor rootDescriptor, string deviceUuid, DataTypeResolverDlgt dataTypeResolver) { return(DoConnect(rootDescriptor, deviceUuid, dataTypeResolver)); }
/// <summary> /// Establishes the actual device connection by building the control point's proxy device tree corresponding to the /// device contained in the given <paramref name="rootDescriptor"/> specified by its <paramref name="deviceUUID"/>. /// </summary> /// <param name="rootDescriptor">Root descriptor which contains the device to build.</param> /// <param name="deviceUUID">UUID of the device to connect.</param> /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param> private void BuildDeviceProxy(RootDescriptor rootDescriptor, string deviceUUID, DataTypeResolverDlgt dataTypeResolver) { if (rootDescriptor.State != RootDescriptorState.Ready) throw new ArgumentException("Root descriptor is not ready - cannot connect"); DeviceDescriptor rootDeviceDescriptor = DeviceDescriptor.CreateRootDeviceDescriptor(rootDescriptor); DeviceDescriptor deviceDescriptor = rootDeviceDescriptor.FindDevice(deviceUUID); _device = CpDevice.ConnectDevice(this, deviceDescriptor, dataTypeResolver); }
protected void InvalidateDescriptor(RootDescriptor rd) { rd.State = RootDescriptorState.Invalid; foreach (IDictionary<string, ServiceDescriptor> sdDict in rd.ServiceDescriptors.Values) foreach (ServiceDescriptor sd in sdDict.Values) sd.State = ServiceDescriptorState.Invalid; }
protected void TryConnect(RootDescriptor rootDescriptor) { DeviceConnection connection; string deviceUuid; lock (_networkTracker.SharedControlPointData.SyncObj) { if (_connection != null) return; DeviceDescriptor rootDeviceDescriptor = DeviceDescriptor.CreateRootDeviceDescriptor(rootDescriptor); DeviceDescriptor backendServerDescriptor = rootDeviceDescriptor.FindFirstDevice( UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE_VERSION); if (backendServerDescriptor == null) return; deviceUuid = backendServerDescriptor.DeviceUUID; string friendlyName = backendServerDescriptor.FriendlyName; SystemName system = new SystemName(new Uri(rootDescriptor.SSDPRootEntry.PreferredLink.DescriptionLocation).Host); if (deviceUuid == _homeServerSystemId) ServiceRegistration.Get<ILogger>().Debug("UPnPClientControlPoint: Found MP2 home server '{0}' (system ID '{1}') at host '{2}' (IP address: '{3}')", friendlyName, deviceUuid, system.HostName, system.Address); else { ServiceRegistration.Get<ILogger>().Debug("UPnPClientControlPoint: Found foreign MP2 server '{0}' (system ID '{1}') at host '{2}' (IP address: '{3}')", friendlyName, deviceUuid, system.HostName, system.Address); return; } try { connection = _connection = _controlPoint.Connect(rootDescriptor, deviceUuid, UPnPExtendedDataTypes.ResolveDataType); } catch (Exception e) { ServiceRegistration.Get<ILogger>().Warn("UPnPClientControlPoint: Error connecting to UPnP MP2 backend server '{0}'", e, deviceUuid); return; } } connection.DeviceDisconnected += OnUPnPDeviceDisconnected; try { CpService cdsStub = connection.Device.FindServiceByServiceId(UPnPTypesAndIds.CONTENT_DIRECTORY_SERVICE_ID); if (cdsStub == null) throw new InvalidDataException("ContentDirectory service not found in device '{0}' of type '{1}:{2}'", deviceUuid, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE_VERSION); CpService risStub = connection.Device.FindServiceByServiceId(UPnPTypesAndIds.RESOURCE_INFORMATION_SERVICE_ID); if (risStub == null) throw new InvalidDataException("ResourceAccess service not found in device '{0}' of type '{1}:{2}'", deviceUuid, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE_VERSION); CpService scsStub = connection.Device.FindServiceByServiceId(UPnPTypesAndIds.SERVER_CONTROLLER_SERVICE_ID); if (scsStub == null) throw new InvalidDataException("ServerController service not found in device '{0}' of type '{1}:{2}'", deviceUuid, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE_VERSION); CpService updmStub = connection.Device.FindServiceByServiceId(UPnPTypesAndIds.USER_PROFILE_DATA_MANAGEMENT_SERVICE_ID); if (updmStub == null) throw new InvalidDataException("UserProfileDataManagement service not found in device '{0}' of type '{1}:{2}'", deviceUuid, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE_VERSION); lock (_networkTracker.SharedControlPointData.SyncObj) { _contentDirectoryService = new UPnPContentDirectoryServiceProxy(cdsStub); _resourceInformationService = new UPnPResourceInformationServiceProxy(risStub); _serverControllerService = new UPnPServerControllerServiceProxy(scsStub); _userProfileDataManagementService = new UPnPUserProfileDataManagementServiceProxy(updmStub); } ICollection<UPnPServiceProxyBase> additionalServices = new List<UPnPServiceProxyBase>(); foreach (AdditionalServiceRegisterDlgt additionalServiceRegistration in _additionalServiceRegistrations) { try { additionalServices.Add(additionalServiceRegistration(connection)); } catch (Exception e) { ServiceRegistration.Get<ILogger>().Warn("UPnPClientControlPoint: Error registering user service for UPnP MP2 backend server '{0}'", e, deviceUuid); } } lock (_networkTracker.SharedControlPointData.SyncObj) _additionalServices = additionalServices; } catch (Exception e) { ServiceRegistration.Get<ILogger>().Warn("UPnPClientControlPoint: Error connecting to services of UPnP MP2 backend server '{0}'", e, deviceUuid); connection.DeviceDisconnected -= OnUPnPDeviceDisconnected; _controlPoint.Disconnect(deviceUuid); return; } InvokeBackendServerDeviceConnected(connection); }
private void HandleDeviceConfigurationChanged(RootDescriptor rootDescriptor) { // Configuration changes cannot be given to our clients because they need a re-initialization of the // device and all service description documents. So configuration changes will be handled by invocing a // root device remove/add event combination. The add event will be fired when the initialization of the root descriptor has finished. InvokeRootDeviceRemoved(rootDescriptor); InitializeRootDescriptor(rootDescriptor.SSDPRootEntry); }
protected void InvokeDeviceRebooted(RootDescriptor rd) { try { DeviceRebootedDlgt dlgt = DeviceRebooted; if (dlgt != null) dlgt(rd); } catch (Exception e) { UPnPConfiguration.LOGGER.Warn("UPnPNetworkTracker: Error invoking DeviceRebooted delegate", e); } }
protected void InitializeRootDescriptor(RootEntry rootEntry) { RootDescriptor rd = new RootDescriptor(rootEntry) { State = RootDescriptorState.AwaitingDeviceDescription }; lock (_cpData.SyncObj) SetRootDescriptor(rootEntry, rd); try { LinkData preferredLink = rootEntry.PreferredLink; HttpWebRequest request = CreateHttpGetRequest(new Uri(preferredLink.DescriptionLocation), preferredLink.Endpoint.EndPointIPAddress); DescriptionRequestState state = new DescriptionRequestState(rd, request); lock (_cpData.SyncObj) _pendingRequests.Add(state); IAsyncResult result = request.BeginGetResponse(OnDeviceDescriptionReceived, state); NetworkHelper.AddTimeout(request, result, PENDING_REQUEST_TIMEOUT * 1000); } catch (Exception) // Don't log messages at this low protocol level { lock (_cpData.SyncObj) rd.State = RootDescriptorState.Erroneous; } }
void OnUPnPRootDeviceAdded(RootDescriptor rootDescriptor) { ClientDescriptor clientDescriptor; lock (_networkTracker.SharedControlPointData.SyncObj) { clientDescriptor = ClientDescriptor.GetMPFrontendServerDescriptor(rootDescriptor); if (clientDescriptor == null || _availableClients.Contains(clientDescriptor)) return; ServiceRegistration.Get<ILogger>().Debug("UPnPServerControlPoint: Found MP2 client '{0}' (system ID '{1}') at host '{2}' ({3})", clientDescriptor.ClientName, clientDescriptor.MPFrontendServerUUID, clientDescriptor.System.HostName, _attachedClientSystemIds.Contains(clientDescriptor.MPFrontendServerUUID) ? "attached" : "not attached"); _availableClients.Add(clientDescriptor); } InvokeClientAvailable(clientDescriptor); CheckConnect(clientDescriptor); }
protected void SetRootDescriptor(RootEntry rootEntry, RootDescriptor rootDescriptor) { rootEntry.ClientProperties[KEY_ROOT_DESCRIPTOR] = rootDescriptor; }
/// <summary> /// Connects to the device of the given <paramref name="deviceUuid"/> specified in the <paramref name="rootDescriptor"/>. /// </summary> /// <param name="rootDescriptor">UPnP root descriptor to connect.</param> /// <param name="deviceUuid">UUID of the device in the root descriptor which is the node to connect.</param> /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param> /// <exception cref="ArgumentException"> /// <list type="bullet"> /// <item>If the device with the specified <paramref name="deviceUuid"/> isn't present /// in the given <paramref name="rootDescriptor"/></item> /// <item>If the given <paramref name="rootDescriptor"/> has is in an erroneous state /// (<c><see cref="RootDescriptor.State"/> == <see cref="RootDescriptorState.Erroneous"/></c>)</item> /// <item>If the given <paramref name="rootDescriptor"/> contains erroneous data, e.g. erroneous device or /// service descriptions</item> /// </list> /// </exception> public DeviceConnection Connect(RootDescriptor rootDescriptor, string deviceUuid, DataTypeResolverDlgt dataTypeResolver) { return DoConnect(rootDescriptor, deviceUuid, dataTypeResolver); }
public DescriptionRequestState(RootDescriptor rootDescriptor, HttpWebRequest httpWebRequest) { _rootDescriptor = rootDescriptor; _httpWebRequest = httpWebRequest; }