aboutsummaryrefslogtreecommitdiff
path: root/RSSDP
diff options
context:
space:
mode:
Diffstat (limited to 'RSSDP')
-rw-r--r--RSSDP/SsdpCommunicationsServer.cs124
-rw-r--r--RSSDP/SsdpDeviceLocator.cs42
-rw-r--r--RSSDP/SsdpDevicePublisher.cs89
3 files changed, 125 insertions, 130 deletions
diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs
index 0dce6c3bf..a3f30c174 100644
--- a/RSSDP/SsdpCommunicationsServer.cs
+++ b/RSSDP/SsdpCommunicationsServer.cs
@@ -32,10 +32,10 @@ namespace Rssdp.Infrastructure
* port to use, we will default to 0 which allows the underlying system to auto-assign a free port.
*/
- private object _BroadcastListenSocketSynchroniser = new object();
+ private object _BroadcastListenSocketSynchroniser = new();
private List<Socket> _MulticastListenSockets;
- private object _SendSocketSynchroniser = new object();
+ private object _SendSocketSynchroniser = new();
private List<Socket> _sendSockets;
private HttpRequestParser _RequestParser;
@@ -48,7 +48,6 @@ namespace Rssdp.Infrastructure
private int _MulticastTtl;
private bool _IsShared;
- private readonly bool _enableMultiSocketBinding;
/// <summary>
/// Raised when a HTTPU request message is received by a socket (unicast or multicast).
@@ -64,9 +63,11 @@ namespace Rssdp.Infrastructure
/// Minimum constructor.
/// </summary>
/// <exception cref="ArgumentNullException">The <paramref name="socketFactory"/> argument is null.</exception>
- public SsdpCommunicationsServer(ISocketFactory socketFactory,
- INetworkManager networkManager, ILogger logger, bool enableMultiSocketBinding)
- : this(socketFactory, 0, SsdpConstants.SsdpDefaultMulticastTimeToLive, networkManager, logger, enableMultiSocketBinding)
+ public SsdpCommunicationsServer(
+ ISocketFactory socketFactory,
+ INetworkManager networkManager,
+ ILogger logger)
+ : this(socketFactory, 0, SsdpConstants.SsdpDefaultMulticastTimeToLive, networkManager, logger)
{
}
@@ -76,7 +77,12 @@ namespace Rssdp.Infrastructure
/// </summary>
/// <exception cref="ArgumentNullException">The <paramref name="socketFactory"/> argument is null.</exception>
/// <exception cref="ArgumentOutOfRangeException">The <paramref name="multicastTimeToLive"/> argument is less than or equal to zero.</exception>
- public SsdpCommunicationsServer(ISocketFactory socketFactory, int localPort, int multicastTimeToLive, INetworkManager networkManager, ILogger logger, bool enableMultiSocketBinding)
+ public SsdpCommunicationsServer(
+ ISocketFactory socketFactory,
+ int localPort,
+ int multicastTimeToLive,
+ INetworkManager networkManager,
+ ILogger logger)
{
if (socketFactory is null)
{
@@ -88,19 +94,18 @@ namespace Rssdp.Infrastructure
throw new ArgumentOutOfRangeException(nameof(multicastTimeToLive), "multicastTimeToLive must be greater than zero.");
}
- _BroadcastListenSocketSynchroniser = new object();
- _SendSocketSynchroniser = new object();
+ _BroadcastListenSocketSynchroniser = new();
+ _SendSocketSynchroniser = new();
_LocalPort = localPort;
_SocketFactory = socketFactory;
- _RequestParser = new HttpRequestParser();
- _ResponseParser = new HttpResponseParser();
+ _RequestParser = new();
+ _ResponseParser = new();
_MulticastTtl = multicastTimeToLive;
_networkManager = networkManager;
_logger = logger;
- _enableMultiSocketBinding = enableMultiSocketBinding;
}
/// <summary>
@@ -335,7 +340,7 @@ namespace Rssdp.Infrastructure
{
sockets = sockets.ToList();
- var tasks = sockets.Where(s => (fromlocalIPAddress is null || fromlocalIPAddress.Equals(((IPEndPoint)s.LocalEndPoint).Address)))
+ var tasks = sockets.Where(s => fromlocalIPAddress is null || fromlocalIPAddress.Equals(((IPEndPoint)s.LocalEndPoint).Address))
.Select(s => SendFromSocket(s, messageData, destination, cancellationToken));
return Task.WhenAll(tasks);
}
@@ -347,33 +352,26 @@ namespace Rssdp.Infrastructure
{
var sockets = new List<Socket>();
var multicastGroupAddress = IPAddress.Parse(SsdpConstants.MulticastLocalAdminAddress);
- if (_enableMultiSocketBinding)
- {
- // IPv6 is currently unsupported
- var validInterfaces = _networkManager.GetInternalBindAddresses()
- .Where(x => x.Address is not null)
- .Where(x => x.AddressFamily == AddressFamily.InterNetwork)
- .DistinctBy(x => x.Index);
- foreach (var intf in validInterfaces)
+ // IPv6 is currently unsupported
+ var validInterfaces = _networkManager.GetInternalBindAddresses()
+ .Where(x => x.Address is not null)
+ .Where(x => x.SupportsMulticast)
+ .Where(x => x.AddressFamily == AddressFamily.InterNetwork)
+ .DistinctBy(x => x.Index);
+
+ foreach (var intf in validInterfaces)
+ {
+ try
{
- try
- {
- var socket = _SocketFactory.CreateUdpMulticastSocket(multicastGroupAddress, intf, _MulticastTtl, SsdpConstants.MulticastPort);
- _ = ListenToSocketInternal(socket);
- sockets.Add(socket);
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "Error in CreateMulticastSocketsAndListen. IP address: {0}", intf.Address);
- }
+ var socket = _SocketFactory.CreateUdpMulticastSocket(multicastGroupAddress, intf, _MulticastTtl, SsdpConstants.MulticastPort);
+ _ = ListenToSocketInternal(socket);
+ sockets.Add(socket);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Failed to create SSDP UDP multicast socket for {0} on interface {1} (index {2})", intf.Address, intf.Name, intf.Index);
}
- }
- else
- {
- var socket = _SocketFactory.CreateUdpMulticastSocket(multicastGroupAddress, new IPData(IPAddress.Any, null), _MulticastTtl, SsdpConstants.MulticastPort);
- _ = ListenToSocketInternal(socket);
- sockets.Add(socket);
}
return sockets;
@@ -382,34 +380,32 @@ namespace Rssdp.Infrastructure
private List<Socket> CreateSendSockets()
{
var sockets = new List<Socket>();
- if (_enableMultiSocketBinding)
+
+ // IPv6 is currently unsupported
+ var validInterfaces = _networkManager.GetInternalBindAddresses()
+ .Where(x => x.Address is not null)
+ .Where(x => x.SupportsMulticast)
+ .Where(x => x.AddressFamily == AddressFamily.InterNetwork);
+
+ if (OperatingSystem.IsMacOS())
{
- // IPv6 is currently unsupported
- var validInterfaces = _networkManager.GetInternalBindAddresses()
- .Where(x => x.Address is not null)
- .Where(x => x.AddressFamily == AddressFamily.InterNetwork);
+ // Manually remove loopback on macOS due to https://github.com/dotnet/runtime/issues/24340
+ validInterfaces = validInterfaces.Where(x => !x.Address.Equals(IPAddress.Loopback));
+ }
- foreach (var intf in validInterfaces)
+ foreach (var intf in validInterfaces)
+ {
+ try
{
- try
- {
- var socket = _SocketFactory.CreateSsdpUdpSocket(intf, _LocalPort);
- _ = ListenToSocketInternal(socket);
- sockets.Add(socket);
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "Error in CreateSsdpUdpSocket. IPAddress: {0}", intf.Address);
- }
+ var socket = _SocketFactory.CreateSsdpUdpSocket(intf, _LocalPort);
+ _ = ListenToSocketInternal(socket);
+ sockets.Add(socket);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Failed to create SSDP UDP sender socket for {0} on interface {1} (index {2})", intf.Address, intf.Name, intf.Index);
}
}
- else
- {
- var socket = _SocketFactory.CreateSsdpUdpSocket(new IPData(IPAddress.Any, null), _LocalPort);
- _ = ListenToSocketInternal(socket);
- sockets.Add(socket);
- }
-
return sockets;
}
@@ -423,7 +419,7 @@ namespace Rssdp.Infrastructure
{
try
{
- var result = await socket.ReceiveMessageFromAsync(receiveBuffer, SocketFlags.None, new IPEndPoint(IPAddress.Any, 0), CancellationToken.None).ConfigureAwait(false);;
+ var result = await socket.ReceiveMessageFromAsync(receiveBuffer, new IPEndPoint(IPAddress.Any, _LocalPort), CancellationToken.None).ConfigureAwait(false);;
if (result.ReceivedBytes > 0)
{
@@ -431,7 +427,7 @@ namespace Rssdp.Infrastructure
var localEndpointAdapter = _networkManager.GetAllBindInterfaces().First(a => a.Index == result.PacketInformation.Interface);
ProcessMessage(
- UTF8Encoding.UTF8.GetString(receiveBuffer, 0, result.ReceivedBytes),
+ Encoding.UTF8.GetString(receiveBuffer, 0, result.ReceivedBytes),
remoteEndpoint,
localEndpointAdapter.Address);
}
@@ -511,7 +507,7 @@ namespace Rssdp.Infrastructure
return;
}
- var handlers = this.RequestReceived;
+ var handlers = RequestReceived;
if (handlers is not null)
{
handlers(this, new RequestReceivedEventArgs(data, remoteEndPoint, receivedOnlocalIPAddress));
@@ -520,7 +516,7 @@ namespace Rssdp.Infrastructure
private void OnResponseReceived(HttpResponseMessage data, IPEndPoint endPoint, IPAddress localIPAddress)
{
- var handlers = this.ResponseReceived;
+ var handlers = ResponseReceived;
if (handlers is not null)
{
handlers(this, new ResponseReceivedEventArgs(data, endPoint)
diff --git a/RSSDP/SsdpDeviceLocator.cs b/RSSDP/SsdpDeviceLocator.cs
index 59f4c5070..82b09c4b4 100644
--- a/RSSDP/SsdpDeviceLocator.cs
+++ b/RSSDP/SsdpDeviceLocator.cs
@@ -17,7 +17,7 @@ namespace Rssdp.Infrastructure
private ISsdpCommunicationsServer _CommunicationsServer;
private Timer _BroadcastTimer;
- private object _timerLock = new object();
+ private object _timerLock = new();
private string _OSName;
@@ -221,12 +221,12 @@ namespace Rssdp.Infrastructure
/// <seealso cref="DeviceAvailable"/>
protected virtual void OnDeviceAvailable(DiscoveredSsdpDevice device, bool isNewDevice, IPAddress IPAddress)
{
- if (this.IsDisposed)
+ if (IsDisposed)
{
return;
}
- var handlers = this.DeviceAvailable;
+ var handlers = DeviceAvailable;
if (handlers is not null)
{
handlers(this, new DeviceAvailableEventArgs(device, isNewDevice)
@@ -244,12 +244,12 @@ namespace Rssdp.Infrastructure
/// <seealso cref="DeviceUnavailable"/>
protected virtual void OnDeviceUnavailable(DiscoveredSsdpDevice device, bool expired)
{
- if (this.IsDisposed)
+ if (IsDisposed)
{
return;
}
- var handlers = this.DeviceUnavailable;
+ var handlers = DeviceUnavailable;
if (handlers is not null)
{
handlers(this, new DeviceUnavailableEventArgs(device, expired));
@@ -291,8 +291,8 @@ namespace Rssdp.Infrastructure
_CommunicationsServer = null;
if (commsServer is not null)
{
- commsServer.ResponseReceived -= this.CommsServer_ResponseReceived;
- commsServer.RequestReceived -= this.CommsServer_RequestReceived;
+ commsServer.ResponseReceived -= CommsServer_ResponseReceived;
+ commsServer.RequestReceived -= CommsServer_RequestReceived;
}
}
}
@@ -341,7 +341,7 @@ namespace Rssdp.Infrastructure
var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
- values["HOST"] = "239.255.255.250:1900";
+ values["HOST"] = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", SsdpConstants.MulticastLocalAdminAddress, SsdpConstants.MulticastPort);
values["USER-AGENT"] = string.Format(CultureInfo.InvariantCulture, "{0}/{1} UPnP/1.0 RSSDP/{2}", _OSName, _OSVersion, SsdpConstants.ServerVersion);
values["MAN"] = "\"ssdp:discover\"";
@@ -382,17 +382,17 @@ namespace Rssdp.Infrastructure
private void ProcessNotificationMessage(HttpRequestMessage message, IPAddress IPAddress)
{
- if (String.Compare(message.Method.Method, "Notify", StringComparison.OrdinalIgnoreCase) != 0)
+ if (string.Compare(message.Method.Method, "Notify", StringComparison.OrdinalIgnoreCase) != 0)
{
return;
}
var notificationType = GetFirstHeaderStringValue("NTS", message);
- if (String.Compare(notificationType, SsdpConstants.SsdpKeepAliveNotification, StringComparison.OrdinalIgnoreCase) == 0)
+ if (string.Compare(notificationType, SsdpConstants.SsdpKeepAliveNotification, StringComparison.OrdinalIgnoreCase) == 0)
{
ProcessAliveNotification(message, IPAddress);
}
- else if (String.Compare(notificationType, SsdpConstants.SsdpByeByeNotification, StringComparison.OrdinalIgnoreCase) == 0)
+ else if (string.Compare(notificationType, SsdpConstants.SsdpByeByeNotification, StringComparison.OrdinalIgnoreCase) == 0)
{
ProcessByeByeNotification(message);
}
@@ -420,7 +420,7 @@ namespace Rssdp.Infrastructure
private void ProcessByeByeNotification(HttpRequestMessage message)
{
var notficationType = GetFirstHeaderStringValue("NT", message);
- if (!String.IsNullOrEmpty(notficationType))
+ if (!string.IsNullOrEmpty(notficationType))
{
var usn = GetFirstHeaderStringValue("USN", message);
@@ -447,10 +447,9 @@ namespace Rssdp.Infrastructure
private string GetFirstHeaderStringValue(string headerName, HttpResponseMessage message)
{
string retVal = null;
- IEnumerable<string> values;
if (message.Headers.Contains(headerName))
{
- message.Headers.TryGetValues(headerName, out values);
+ message.Headers.TryGetValues(headerName, out var values);
if (values is not null)
{
retVal = values.FirstOrDefault();
@@ -463,10 +462,9 @@ namespace Rssdp.Infrastructure
private string GetFirstHeaderStringValue(string headerName, HttpRequestMessage message)
{
string retVal = null;
- IEnumerable<string> values;
if (message.Headers.Contains(headerName))
{
- message.Headers.TryGetValues(headerName, out values);
+ message.Headers.TryGetValues(headerName, out var values);
if (values is not null)
{
retVal = values.FirstOrDefault();
@@ -479,10 +477,9 @@ namespace Rssdp.Infrastructure
private Uri GetFirstHeaderUriValue(string headerName, HttpRequestMessage request)
{
string value = null;
- IEnumerable<string> values;
if (request.Headers.Contains(headerName))
{
- request.Headers.TryGetValues(headerName, out values);
+ request.Headers.TryGetValues(headerName, out var values);
if (values is not null)
{
value = values.FirstOrDefault();
@@ -496,10 +493,9 @@ namespace Rssdp.Infrastructure
private Uri GetFirstHeaderUriValue(string headerName, HttpResponseMessage response)
{
string value = null;
- IEnumerable<string> values;
if (response.Headers.Contains(headerName))
{
- response.Headers.TryGetValues(headerName, out values);
+ response.Headers.TryGetValues(headerName, out var values);
if (values is not null)
{
value = values.FirstOrDefault();
@@ -529,7 +525,7 @@ namespace Rssdp.Infrastructure
foreach (var device in expiredDevices)
{
- if (this.IsDisposed)
+ if (IsDisposed)
{
return;
}
@@ -543,7 +539,7 @@ namespace Rssdp.Infrastructure
// problems.
foreach (var expiredUsn in (from expiredDevice in expiredDevices select expiredDevice.Usn).Distinct())
{
- if (this.IsDisposed)
+ if (IsDisposed)
{
return;
}
@@ -560,7 +556,7 @@ namespace Rssdp.Infrastructure
existingDevices = FindExistingDeviceNotifications(_Devices, deviceUsn);
foreach (var existingDevice in existingDevices)
{
- if (this.IsDisposed)
+ if (IsDisposed)
{
return true;
}
diff --git a/RSSDP/SsdpDevicePublisher.cs b/RSSDP/SsdpDevicePublisher.cs
index 950e6fec8..65ae658a4 100644
--- a/RSSDP/SsdpDevicePublisher.cs
+++ b/RSSDP/SsdpDevicePublisher.cs
@@ -206,9 +206,9 @@ namespace Rssdp.Infrastructure
IPAddress receivedOnlocalIPAddress,
CancellationToken cancellationToken)
{
- if (String.IsNullOrEmpty(searchTarget))
+ if (string.IsNullOrEmpty(searchTarget))
{
- WriteTrace(String.Format(CultureInfo.InvariantCulture, "Invalid search request received From {0}, Target is null/empty.", remoteEndPoint.ToString()));
+ WriteTrace(string.Format(CultureInfo.InvariantCulture, "Invalid search request received From {0}, Target is null/empty.", remoteEndPoint.ToString()));
return;
}
@@ -232,7 +232,7 @@ namespace Rssdp.Infrastructure
// return;
}
- if (!Int32.TryParse(mx, out var maxWaitInterval) || maxWaitInterval <= 0)
+ if (!int.TryParse(mx, out var maxWaitInterval) || maxWaitInterval <= 0)
{
return;
}
@@ -243,27 +243,27 @@ namespace Rssdp.Infrastructure
}
// Do not block synchronously as that may tie up a threadpool thread for several seconds.
- Task.Delay(_Random.Next(16, (maxWaitInterval * 1000))).ContinueWith((parentTask) =>
+ Task.Delay(_Random.Next(16, maxWaitInterval * 1000)).ContinueWith((parentTask) =>
{
// Copying devices to local array here to avoid threading issues/enumerator exceptions.
IEnumerable<SsdpDevice> devices = null;
lock (_Devices)
{
- if (String.Compare(SsdpConstants.SsdpDiscoverAllSTHeader, searchTarget, StringComparison.OrdinalIgnoreCase) == 0)
+ if (string.Compare(SsdpConstants.SsdpDiscoverAllSTHeader, searchTarget, StringComparison.OrdinalIgnoreCase) == 0)
{
devices = GetAllDevicesAsFlatEnumerable().ToArray();
}
- else if (String.Compare(SsdpConstants.UpnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 || (this.SupportPnpRootDevice && String.Compare(SsdpConstants.PnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0))
+ else if (string.Compare(SsdpConstants.UpnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 || (SupportPnpRootDevice && String.Compare(SsdpConstants.PnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0))
{
devices = _Devices.ToArray();
}
else if (searchTarget.Trim().StartsWith("uuid:", StringComparison.OrdinalIgnoreCase))
{
- devices = GetAllDevicesAsFlatEnumerable().Where(d => String.Compare(d.Uuid, searchTarget.Substring(5), StringComparison.OrdinalIgnoreCase) == 0).ToArray();
+ devices = GetAllDevicesAsFlatEnumerable().Where(d => string.Compare(d.Uuid, searchTarget.Substring(5), StringComparison.OrdinalIgnoreCase) == 0).ToArray();
}
else if (searchTarget.StartsWith("urn:", StringComparison.OrdinalIgnoreCase))
{
- devices = GetAllDevicesAsFlatEnumerable().Where(d => String.Compare(d.FullDeviceType, searchTarget, StringComparison.OrdinalIgnoreCase) == 0).ToArray();
+ devices = GetAllDevicesAsFlatEnumerable().Where(d => string.Compare(d.FullDeviceType, searchTarget, StringComparison.OrdinalIgnoreCase) == 0).ToArray();
}
}
@@ -299,7 +299,7 @@ namespace Rssdp.Infrastructure
if (isRootDevice)
{
SendSearchResponse(SsdpConstants.UpnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.UpnpDeviceTypeRootDevice), endPoint, receivedOnlocalIPAddress, cancellationToken);
- if (this.SupportPnpRootDevice)
+ if (SupportPnpRootDevice)
{
SendSearchResponse(SsdpConstants.PnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.PnpDeviceTypeRootDevice), endPoint, receivedOnlocalIPAddress, cancellationToken);
}
@@ -312,7 +312,7 @@ namespace Rssdp.Infrastructure
private string GetUsn(string udn, string fullDeviceType)
{
- return String.Format(CultureInfo.InvariantCulture, "{0}::{1}", udn, fullDeviceType);
+ return string.Format(CultureInfo.InvariantCulture, "{0}::{1}", udn, fullDeviceType);
}
private async void SendSearchResponse(
@@ -326,16 +326,17 @@ namespace Rssdp.Infrastructure
const string header = "HTTP/1.1 200 OK";
var rootDevice = device.ToRootDevice();
- var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
-
- values["EXT"] = "";
- values["DATE"] = DateTime.UtcNow.ToString("r");
- values["HOST"] = "239.255.255.250:1900";
- values["CACHE-CONTROL"] = "max-age = " + rootDevice.CacheLifetime.TotalSeconds;
- values["ST"] = searchTarget;
- values["SERVER"] = string.Format(CultureInfo.InvariantCulture, "{0}/{1} UPnP/1.0 RSSDP/{2}", _OSName, _OSVersion, SsdpConstants.ServerVersion);
- values["USN"] = uniqueServiceName;
- values["LOCATION"] = rootDevice.Location.ToString();
+ var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
+ {
+ ["EXT"] = "",
+ ["DATE"] = DateTime.UtcNow.ToString("r"),
+ ["HOST"] = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", SsdpConstants.MulticastLocalAdminAddress, SsdpConstants.MulticastPort),
+ ["CACHE-CONTROL"] = "max-age = " + rootDevice.CacheLifetime.TotalSeconds,
+ ["ST"] = searchTarget,
+ ["SERVER"] = string.Format(CultureInfo.InvariantCulture, "{0}/{1} UPnP/1.0 RSSDP/{2}", _OSName, _OSVersion, SsdpConstants.ServerVersion),
+ ["USN"] = uniqueServiceName,
+ ["LOCATION"] = rootDevice.Location.ToString()
+ };
var message = BuildMessage(header, values);
@@ -439,7 +440,7 @@ namespace Rssdp.Infrastructure
if (isRoot)
{
SendAliveNotification(device, SsdpConstants.UpnpDeviceTypeRootDevice, GetUsn(device.Udn, SsdpConstants.UpnpDeviceTypeRootDevice), cancellationToken);
- if (this.SupportPnpRootDevice)
+ if (SupportPnpRootDevice)
{
SendAliveNotification(device, SsdpConstants.PnpDeviceTypeRootDevice, GetUsn(device.Udn, SsdpConstants.PnpDeviceTypeRootDevice), cancellationToken);
}
@@ -460,17 +461,18 @@ namespace Rssdp.Infrastructure
const string header = "NOTIFY * HTTP/1.1";
- var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
-
- // If needed later for non-server devices, these headers will need to be dynamic
- values["HOST"] = "239.255.255.250:1900";
- values["DATE"] = DateTime.UtcNow.ToString("r");
- values["CACHE-CONTROL"] = "max-age = " + rootDevice.CacheLifetime.TotalSeconds;
- values["LOCATION"] = rootDevice.Location.ToString();
- values["SERVER"] = string.Format(CultureInfo.InvariantCulture, "{0}/{1} UPnP/1.0 RSSDP/{2}", _OSName, _OSVersion, SsdpConstants.ServerVersion);
- values["NTS"] = "ssdp:alive";
- values["NT"] = notificationType;
- values["USN"] = uniqueServiceName;
+ var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
+ {
+ // If needed later for non-server devices, these headers will need to be dynamic
+ ["HOST"] = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", SsdpConstants.MulticastLocalAdminAddress, SsdpConstants.MulticastPort),
+ ["DATE"] = DateTime.UtcNow.ToString("r"),
+ ["CACHE-CONTROL"] = "max-age = " + rootDevice.CacheLifetime.TotalSeconds,
+ ["LOCATION"] = rootDevice.Location.ToString(),
+ ["SERVER"] = string.Format(CultureInfo.InvariantCulture, "{0}/{1} UPnP/1.0 RSSDP/{2}", _OSName, _OSVersion, SsdpConstants.ServerVersion),
+ ["NTS"] = "ssdp:alive",
+ ["NT"] = notificationType,
+ ["USN"] = uniqueServiceName
+ };
var message = BuildMessage(header, values);
@@ -485,7 +487,7 @@ namespace Rssdp.Infrastructure
if (isRoot)
{
tasks.Add(SendByeByeNotification(device, SsdpConstants.UpnpDeviceTypeRootDevice, GetUsn(device.Udn, SsdpConstants.UpnpDeviceTypeRootDevice), cancellationToken));
- if (this.SupportPnpRootDevice)
+ if (SupportPnpRootDevice)
{
tasks.Add(SendByeByeNotification(device, "pnp:rootdevice", GetUsn(device.Udn, "pnp:rootdevice"), cancellationToken));
}
@@ -506,20 +508,21 @@ namespace Rssdp.Infrastructure
{
const string header = "NOTIFY * HTTP/1.1";
- var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
-
- // If needed later for non-server devices, these headers will need to be dynamic
- values["HOST"] = "239.255.255.250:1900";
- values["DATE"] = DateTime.UtcNow.ToString("r");
- values["SERVER"] = string.Format(CultureInfo.InvariantCulture, "{0}/{1} UPnP/1.0 RSSDP/{2}", _OSName, _OSVersion, SsdpConstants.ServerVersion);
- values["NTS"] = "ssdp:byebye";
- values["NT"] = notificationType;
- values["USN"] = uniqueServiceName;
+ var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
+ {
+ // If needed later for non-server devices, these headers will need to be dynamic
+ ["HOST"] = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", SsdpConstants.MulticastLocalAdminAddress, SsdpConstants.MulticastPort),
+ ["DATE"] = DateTime.UtcNow.ToString("r"),
+ ["SERVER"] = string.Format(CultureInfo.InvariantCulture, "{0}/{1} UPnP/1.0 RSSDP/{2}", _OSName, _OSVersion, SsdpConstants.ServerVersion),
+ ["NTS"] = "ssdp:byebye",
+ ["NT"] = notificationType,
+ ["USN"] = uniqueServiceName
+ };
var message = BuildMessage(header, values);
var sendCount = IsDisposed ? 1 : 3;
- WriteTrace(String.Format(CultureInfo.InvariantCulture, "Sent byebye notification"), device);
+ WriteTrace(string.Format(CultureInfo.InvariantCulture, "Sent byebye notification"), device);
return _CommsServer.SendMulticastMessage(message, sendCount, _sendOnlyMatchedHost ? device.ToRootDevice().Address : null, cancellationToken);
}