2021-05-07 05:43:50 -07:00
|
|
|
#nullable disable
|
|
|
|
|
2020-01-22 13:00:07 -07:00
|
|
|
#pragma warning disable CS1591
|
|
|
|
|
2019-01-13 12:54:44 -07:00
|
|
|
using System;
|
2016-10-29 15:22:20 -07:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
2020-08-13 17:48:28 -07:00
|
|
|
using Jellyfin.Data.Events;
|
2019-01-13 12:16:19 -07:00
|
|
|
using MediaBrowser.Controller.Configuration;
|
2016-10-29 15:22:20 -07:00
|
|
|
using MediaBrowser.Model.Dlna;
|
|
|
|
using Rssdp;
|
2016-11-14 12:48:01 -07:00
|
|
|
using Rssdp.Infrastructure;
|
2016-10-29 15:22:20 -07:00
|
|
|
|
2016-10-29 15:34:54 -07:00
|
|
|
namespace Emby.Dlna.Ssdp
|
2016-10-29 15:22:20 -07:00
|
|
|
{
|
2020-01-22 13:00:07 -07:00
|
|
|
public sealed class DeviceDiscovery : IDeviceDiscovery, IDisposable
|
2016-10-29 15:22:20 -07:00
|
|
|
{
|
2020-01-22 13:00:07 -07:00
|
|
|
private readonly object _syncLock = new object();
|
2016-10-29 15:22:20 -07:00
|
|
|
|
|
|
|
private readonly IServerConfigurationManager _config;
|
|
|
|
|
2020-08-20 08:01:04 -07:00
|
|
|
private SsdpDeviceLocator _deviceLocator;
|
|
|
|
private ISsdpCommunicationsServer _commsServer;
|
|
|
|
|
2018-09-12 10:26:21 -07:00
|
|
|
private int _listenerCount;
|
2020-01-22 13:00:07 -07:00
|
|
|
private bool _disposed;
|
|
|
|
|
2020-08-20 08:01:04 -07:00
|
|
|
public DeviceDiscovery(IServerConfigurationManager config)
|
|
|
|
{
|
|
|
|
_config = config;
|
|
|
|
}
|
|
|
|
|
2020-01-22 13:00:07 -07:00
|
|
|
private event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceDiscoveredInternal;
|
2019-11-01 13:22:35 -07:00
|
|
|
|
|
|
|
/// <inheritdoc />
|
2018-09-12 10:26:21 -07:00
|
|
|
public event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceDiscovered
|
|
|
|
{
|
|
|
|
add
|
|
|
|
{
|
|
|
|
lock (_syncLock)
|
|
|
|
{
|
|
|
|
_listenerCount++;
|
|
|
|
DeviceDiscoveredInternal += value;
|
|
|
|
}
|
2019-11-01 13:22:35 -07:00
|
|
|
|
2018-09-12 10:26:21 -07:00
|
|
|
StartInternal();
|
|
|
|
}
|
2020-01-22 13:00:07 -07:00
|
|
|
|
2018-09-12 10:26:21 -07:00
|
|
|
remove
|
|
|
|
{
|
|
|
|
lock (_syncLock)
|
|
|
|
{
|
|
|
|
_listenerCount--;
|
|
|
|
DeviceDiscoveredInternal -= value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-01 13:22:35 -07:00
|
|
|
/// <inheritdoc />
|
2016-10-29 15:22:20 -07:00
|
|
|
public event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceLeft;
|
|
|
|
|
|
|
|
// Call this method from somewhere in your code to start the search.
|
2016-11-14 12:48:01 -07:00
|
|
|
public void Start(ISsdpCommunicationsServer communicationsServer)
|
2016-10-29 15:22:20 -07:00
|
|
|
{
|
2018-09-12 10:26:21 -07:00
|
|
|
_commsServer = communicationsServer;
|
|
|
|
|
|
|
|
StartInternal();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void StartInternal()
|
|
|
|
{
|
|
|
|
lock (_syncLock)
|
|
|
|
{
|
2021-03-10 12:56:33 -07:00
|
|
|
if (_listenerCount > 0 && _deviceLocator == null && _commsServer != null)
|
2018-09-12 10:26:21 -07:00
|
|
|
{
|
2019-02-05 01:49:46 -07:00
|
|
|
_deviceLocator = new SsdpDeviceLocator(_commsServer);
|
2016-10-29 15:22:20 -07:00
|
|
|
|
2019-01-07 16:27:46 -07:00
|
|
|
// (Optional) Set the filter so we only see notifications for devices we care about
|
|
|
|
// (can be any search target value i.e device type, uuid value etc - any value that appears in the
|
2018-09-12 10:26:21 -07:00
|
|
|
// DiscoverdSsdpDevice.NotificationType property or that is used with the searchTarget parameter of the Search method).
|
2020-06-14 02:11:11 -07:00
|
|
|
// _DeviceLocator.NotificationFilter = "upnp:rootdevice";
|
2016-10-29 15:22:20 -07:00
|
|
|
|
2018-09-12 10:26:21 -07:00
|
|
|
// Connect our event handler so we process devices as they are found
|
2019-11-01 13:22:35 -07:00
|
|
|
_deviceLocator.DeviceAvailable += OnDeviceLocatorDeviceAvailable;
|
|
|
|
_deviceLocator.DeviceUnavailable += OnDeviceLocatorDeviceUnavailable;
|
2016-10-29 15:22:20 -07:00
|
|
|
|
2018-09-12 10:26:21 -07:00
|
|
|
var dueTime = TimeSpan.FromSeconds(5);
|
|
|
|
var interval = TimeSpan.FromSeconds(_config.GetDlnaConfiguration().ClientDiscoveryIntervalSeconds);
|
2017-02-05 13:44:08 -07:00
|
|
|
|
2018-09-12 10:26:21 -07:00
|
|
|
_deviceLocator.RestartBroadcastTimer(dueTime, interval);
|
|
|
|
}
|
|
|
|
}
|
2016-10-29 15:22:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Process each found device in the event handler
|
2019-11-01 13:22:35 -07:00
|
|
|
private void OnDeviceLocatorDeviceAvailable(object sender, DeviceAvailableEventArgs e)
|
2016-10-29 15:22:20 -07:00
|
|
|
{
|
|
|
|
var originalHeaders = e.DiscoveredDevice.ResponseHeaders;
|
|
|
|
|
|
|
|
var headerDict = originalHeaders == null ? new Dictionary<string, KeyValuePair<string, IEnumerable<string>>>() : originalHeaders.ToDictionary(i => i.Key, StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
|
|
|
var headers = headerDict.ToDictionary(i => i.Key, i => i.Value.Value.FirstOrDefault(), StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
2020-04-05 09:10:56 -07:00
|
|
|
var args = new GenericEventArgs<UpnpDeviceInfo>(
|
|
|
|
new UpnpDeviceInfo
|
2016-10-29 15:22:20 -07:00
|
|
|
{
|
|
|
|
Location = e.DiscoveredDevice.DescriptionLocation,
|
2017-01-24 12:54:18 -07:00
|
|
|
Headers = headers,
|
2021-04-15 10:36:47 -07:00
|
|
|
RemoteIpAddress = e.RemoteIpAddress
|
2020-04-05 09:10:56 -07:00
|
|
|
});
|
2016-10-29 15:22:20 -07:00
|
|
|
|
2018-12-28 07:21:02 -07:00
|
|
|
DeviceDiscoveredInternal?.Invoke(this, args);
|
2016-10-29 15:22:20 -07:00
|
|
|
}
|
|
|
|
|
2019-11-01 13:22:35 -07:00
|
|
|
private void OnDeviceLocatorDeviceUnavailable(object sender, DeviceUnavailableEventArgs e)
|
2016-10-29 15:22:20 -07:00
|
|
|
{
|
|
|
|
var originalHeaders = e.DiscoveredDevice.ResponseHeaders;
|
|
|
|
|
|
|
|
var headerDict = originalHeaders == null ? new Dictionary<string, KeyValuePair<string, IEnumerable<string>>>() : originalHeaders.ToDictionary(i => i.Key, StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
|
|
|
var headers = headerDict.ToDictionary(i => i.Key, i => i.Value.Value.FirstOrDefault(), StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
2020-04-05 09:10:56 -07:00
|
|
|
var args = new GenericEventArgs<UpnpDeviceInfo>(
|
|
|
|
new UpnpDeviceInfo
|
2016-10-29 15:22:20 -07:00
|
|
|
{
|
|
|
|
Location = e.DiscoveredDevice.DescriptionLocation,
|
|
|
|
Headers = headers
|
2020-04-05 09:10:56 -07:00
|
|
|
});
|
2016-10-29 15:22:20 -07:00
|
|
|
|
2018-12-28 07:21:02 -07:00
|
|
|
DeviceLeft?.Invoke(this, args);
|
2016-10-29 15:22:20 -07:00
|
|
|
}
|
|
|
|
|
2020-01-22 13:00:07 -07:00
|
|
|
/// <inheritdoc />
|
2016-10-29 15:22:20 -07:00
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
if (!_disposed)
|
|
|
|
{
|
|
|
|
_disposed = true;
|
2017-02-07 00:33:24 -07:00
|
|
|
if (_deviceLocator != null)
|
|
|
|
{
|
|
|
|
_deviceLocator.Dispose();
|
|
|
|
_deviceLocator = null;
|
|
|
|
}
|
2016-10-29 15:22:20 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|