jellyfin/Emby.Dlna/Ssdp/DeviceDiscovery.cs

121 lines
4.6 KiB
C#
Raw Normal View History

2016-10-29 22:22:20 +00:00
using MediaBrowser.Common.Events;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Net;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Events;
2016-11-04 08:31:05 +00:00
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Threading;
2016-10-29 22:22:20 +00:00
using Rssdp;
2016-11-14 19:48:01 +00:00
using Rssdp.Infrastructure;
2016-10-29 22:22:20 +00:00
2016-10-29 22:34:54 +00:00
namespace Emby.Dlna.Ssdp
2016-10-29 22:22:20 +00:00
{
2017-02-07 07:33:24 +00:00
public class DeviceDiscovery : IDeviceDiscovery
2016-10-29 22:22:20 +00:00
{
private bool _disposed;
private readonly ILogger _logger;
private readonly IServerConfigurationManager _config;
public event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceDiscovered;
public event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceLeft;
2016-11-14 19:48:01 +00:00
private SsdpDeviceLocator _deviceLocator;
2016-10-29 22:22:20 +00:00
2016-11-04 08:31:05 +00:00
private readonly ITimerFactory _timerFactory;
private readonly ISocketFactory _socketFactory;
public DeviceDiscovery(ILogger logger, IServerConfigurationManager config, ISocketFactory socketFactory, ITimerFactory timerFactory)
2016-10-29 22:22:20 +00:00
{
_logger = logger;
_config = config;
2016-11-04 08:31:05 +00:00
_socketFactory = socketFactory;
_timerFactory = timerFactory;
2016-10-29 22:22:20 +00:00
}
// Call this method from somewhere in your code to start the search.
2016-11-14 19:48:01 +00:00
public void Start(ISsdpCommunicationsServer communicationsServer)
2016-10-29 22:22:20 +00:00
{
2016-11-14 19:48:01 +00:00
_deviceLocator = new SsdpDeviceLocator(communicationsServer, _timerFactory);
2016-10-29 22:22:20 +00: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
// DiscoverdSsdpDevice.NotificationType property or that is used with the searchTarget parameter of the Search method).
//_DeviceLocator.NotificationFilter = "upnp:rootdevice";
// Connect our event handler so we process devices as they are found
2016-11-14 19:48:01 +00:00
_deviceLocator.DeviceAvailable += deviceLocator_DeviceAvailable;
_deviceLocator.DeviceUnavailable += _DeviceLocator_DeviceUnavailable;
2016-10-29 22:22:20 +00:00
2017-02-07 07:33:24 +00:00
var dueTime = TimeSpan.FromSeconds(5);
var interval = TimeSpan.FromSeconds(_config.GetDlnaConfiguration().ClientDiscoveryIntervalSeconds);
2017-02-05 20:44:08 +00:00
2017-02-07 07:33:24 +00:00
_deviceLocator.RestartBroadcastTimer(dueTime, interval);
2016-10-29 22:22:20 +00:00
}
// Process each found device in the event handler
void deviceLocator_DeviceAvailable(object sender, DeviceAvailableEventArgs e)
{
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);
var args = new GenericEventArgs<UpnpDeviceInfo>
{
Argument = new UpnpDeviceInfo
{
Location = e.DiscoveredDevice.DescriptionLocation,
2017-01-24 19:54:18 +00:00
Headers = headers,
LocalIpAddress = e.LocalIpAddress
2016-10-29 22:22:20 +00:00
}
};
EventHelper.FireEventIfNotNull(DeviceDiscovered, this, args, _logger);
}
private void _DeviceLocator_DeviceUnavailable(object sender, DeviceUnavailableEventArgs e)
{
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);
var args = new GenericEventArgs<UpnpDeviceInfo>
{
Argument = new UpnpDeviceInfo
{
Location = e.DiscoveredDevice.DescriptionLocation,
Headers = headers
}
};
EventHelper.FireEventIfNotNull(DeviceLeft, this, args, _logger);
}
public void Dispose()
{
if (!_disposed)
{
_disposed = true;
2017-02-07 07:33:24 +00:00
if (_deviceLocator != null)
{
_deviceLocator.Dispose();
_deviceLocator = null;
}
2016-10-29 22:22:20 +00:00
}
}
}
}