Skip to content

Commit

Permalink
Add generic non-AVM UPnP device search
Browse files Browse the repository at this point in the history
  • Loading branch information
Rans4ckeR committed Jan 30, 2024
1 parent 4fd7e70 commit a2baf5c
Show file tree
Hide file tree
Showing 89 changed files with 1,398 additions and 1,247 deletions.
11 changes: 11 additions & 0 deletions RS.Fritz.Manager.API/Entities/GroupedInternetGatewayDevice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace RS.Fritz.Manager.API;

using System.Collections.Frozen;
using System.Net;

public sealed record GroupedInternetGatewayDevice(
IEnumerable<Uri?>? Locations,
string? Server,
IEnumerable<InternetGatewayDevice> Devices,
Uri? PreferredLocation,
FrozenSet<IPAddress> LocalIpAddresses);
24 changes: 22 additions & 2 deletions RS.Fritz.Manager.API/Entities/InternetGatewayDevice.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
namespace RS.Fritz.Manager.API;

using System.Collections.Frozen;
using System.Net;

public sealed record InternetGatewayDevice(IFritzServiceOperationHandler FritzServiceOperationHandler, IUsersService UsersService, IEnumerable<Uri> Locations, string Server, string CacheControl, string? Ext, string SearchTarget, string UniqueServiceName, UPnPDescription UPnPDescription, Uri PreferredLocation, IReadOnlyCollection<IPAddress> LocalIpAddresses)
public sealed record InternetGatewayDevice(
IFritzServiceOperationHandler FritzServiceOperationHandler,
IUsersService UsersService,
string? CacheControl,
string? Date,
string? Ext,
IEnumerable<Uri?>? Locations,
string? Server,
string? SearchTarget,
string? UniqueServiceName,
string? Options,
string? Nls,
int? BootId,
int? ConfigId,
ushort? SearchPort,
IEnumerable<Uri?>? SecureLocations,
UPnPDescription? UPnPDescription,
Uri? PreferredLocation,
FrozenSet<IPAddress> LocalIpAddresses,
ushort? Version)
{
private IReadOnlyCollection<ServiceListItem>? services;

Expand All @@ -13,7 +33,7 @@ public sealed record InternetGatewayDevice(IFritzServiceOperationHandler FritzSe
public NetworkCredential? NetworkCredential { get; set; }

public IEnumerable<ServiceListItem> Services
=> services ??= UPnPDescription.Device.GetServices().ToArray();
=> services ??= UPnPDescription?.Device?.GetServices().ToArray() ?? [];

public async ValueTask InitializeAsync()
{
Expand Down
12 changes: 6 additions & 6 deletions RS.Fritz.Manager.API/Infrastructure/ExceptionMessageBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ private static void GetExceptionDetails(this StringBuilder sb, Exception ex)
.GetFaultCode(faultException.Code);

#pragma warning disable IDE0045 // Convert to conditional expression
if (ex is FaultException<UPnPFault1> upnpFaultFault1Exception)
if (ex is FaultException<UPnPFault> upnpFaultFaultException)
{
_ = sb.AppendLine(FormattableString.Invariant($"{nameof(UPnPFault1)}.{nameof(UPnPFault1.ErrorCode)}: {upnpFaultFault1Exception.Detail.ErrorCode}"))
.AppendLine(FormattableString.Invariant($"{nameof(UPnPFault1)}.{nameof(UPnPFault1.ErrorDescription)}: {upnpFaultFault1Exception.Detail.ErrorDescription}"));
_ = sb.AppendLine(FormattableString.Invariant($"{nameof(UPnPFault)}.{nameof(UPnPFault.ErrorCode)}: {upnpFaultFaultException.Detail.ErrorCode}"))
.AppendLine(FormattableString.Invariant($"{nameof(UPnPFault)}.{nameof(UPnPFault.ErrorDescription)}: {upnpFaultFaultException.Detail.ErrorDescription}"));
}
else if (ex is FaultException<UPnPFault2> upnpFaultFault2Exception)
else if (ex is FaultException<AvmUPnPFault> avmUpnpFaultFaultException)
{
_ = sb.AppendLine(FormattableString.Invariant($"{nameof(UPnPFault2)}.{nameof(UPnPFault2.ErrorCode)}: {upnpFaultFault2Exception.Detail.ErrorCode}"))
.AppendLine(FormattableString.Invariant($"{nameof(UPnPFault2)}.{nameof(UPnPFault2.ErrorDescription)}: {upnpFaultFault2Exception.Detail.ErrorDescription}"));
_ = sb.AppendLine(FormattableString.Invariant($"{nameof(AvmUPnPFault)}.{nameof(AvmUPnPFault.ErrorCode)}: {avmUpnpFaultFaultException.Detail.ErrorCode}"))
.AppendLine(FormattableString.Invariant($"{nameof(AvmUPnPFault)}.{nameof(AvmUPnPFault.ErrorDescription)}: {avmUpnpFaultFaultException.Detail.ErrorDescription}"));
}
else
{
Expand Down
1 change: 1 addition & 0 deletions RS.Fritz.Manager.API/RS.Fritz.Manager.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<PackageReadmeFile>README.md</PackageReadmeFile>
<EnablePackageValidation>true</EnablePackageValidation>
<Platform>AnyCPU</Platform>
<EnableSourceControlManagerQueries Condition="$(Configuration) == 'Debug'">true</EnableSourceControlManagerQueries> <!--https://github.com/dotnet/sdk/issues/36666-->
</PropertyGroup>
<ItemGroup>
<None Include="..\README.md" Pack="true" PackagePath="\" />
Expand Down
320 changes: 246 additions & 74 deletions RS.Fritz.Manager.API/Services/Discovery/DeviceSearchService.cs

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions RS.Fritz.Manager.API/Services/Discovery/Entities/AvmDevice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = UPnPConstants.Device, Namespace = UPnPConstants.Device10AvmNamespace)]
internal readonly record struct AvmDevice(
[property: DataMember(Name = "deviceType", Order = 0)] string DeviceType,
[property: DataMember(Name = "friendlyName", Order = 1)] string FriendlyName,
[property: DataMember(Name = "manufacturer", Order = 2)] string Manufacturer,
[property: DataMember(Name = "manufacturerURL", Order = 3)] string ManufacturerUrl,
[property: DataMember(Name = "modelDescription", Order = 4)] string ModelDescription,
[property: DataMember(Name = "modelName", Order = 5)] string ModelName,
[property: DataMember(Name = "modelNumber", Order = 6)] string ModelNumber,
[property: DataMember(Name = "modelURL", Order = 7)] string ModelUrl,
[property: DataMember(Name = "UDN", Order = 8)] string UniqueDeviceName,
[property: DataMember(Name = "serialNumber", Order = 9)] string? SerialNumber,
[property: DataMember(Name = "originUDN", Order = 10)] string? OriginUniqueDeviceName,
[property: DataMember(Name = "iconList", Order = 11)] ICollection<AvmIconListItem>? IconList,
[property: DataMember(Name = "serviceList", Order = 12)] ICollection<AvmServiceListItem>? ServiceList,
[property: DataMember(Name = "deviceList", Order = 13)] ICollection<AvmDeviceListDevice>? DeviceList,
[property: DataMember(Name = "presentationURL", Order = 14)] string? PresentationUrl);
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = UPnPConstants.Device, Namespace = UPnPConstants.Device10AvmNamespace)]
internal readonly record struct AvmDeviceListDevice(
[property: DataMember(Name = "deviceType", Order = 0)] string DeviceType,
[property: DataMember(Name = "friendlyName", Order = 1)] string FriendlyName,
[property: DataMember(Name = "manufacturer", Order = 2)] string Manufacturer,
[property: DataMember(Name = "manufacturerURL", Order = 3)] string ManufacturerUrl,
[property: DataMember(Name = "modelDescription", Order = 4)] string ModelDescription,
[property: DataMember(Name = "modelName", Order = 5)] string ModelName,
[property: DataMember(Name = "modelNumber", Order = 6)] string ModelNumber,
[property: DataMember(Name = "modelURL", Order = 7)] string ModelUrl,
[property: DataMember(Name = "UDN", Order = 8)] string UniqueDeviceName,
[property: DataMember(Name = "UPC", Order = 9)] string? UniversalProductCode,
[property: DataMember(Name = "serviceList", Order = 10)] ICollection<AvmServiceListItem>? ServiceList,
[property: DataMember(Name = "deviceList", Order = 11)] ICollection<AvmDeviceListDevice>? DeviceList);
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = UPnPConstants.Icon, Namespace = UPnPConstants.Device10AvmNamespace)]
internal readonly record struct AvmIconListItem(
[property: DataMember(Name = "mimetype", Order = 0)] string Mimetype,
[property: DataMember(Name = "width", Order = 1)] int Width,
[property: DataMember(Name = "height", Order = 2)] int Height,
[property: DataMember(Name = "depth", Order = 3)] int Depth,
[property: DataMember(Name = "url", Order = 4)] string Url);
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = UPnPConstants.Service, Namespace = UPnPConstants.Device10AvmNamespace)]
internal readonly record struct AvmServiceListItem(
[property: DataMember(Name = "serviceType", Order = 0)] string ServiceType,
[property: DataMember(Name = "serviceId", Order = 1)] string ServiceId,
[property: DataMember(Name = "controlURL", Order = 2)] string ControlUrl,
[property: DataMember(Name = "eventSubURL", Order = 3)] string EventSubUrl,
[property: DataMember(Name = "SCPDURL", Order = 4)] string ScpdUrl);
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = UPnPConstants.SpecVersion, Namespace = UPnPConstants.Device10AvmNamespace)]
internal readonly record struct AvmSpecVersion(
[property: DataMember(Name = "major", Order = 0)] int Major,
[property: DataMember(Name = "minor", Order = 1)] int Minor);
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = UPnPConstants.SystemVersion, Namespace = UPnPConstants.Device10AvmNamespace)]
internal readonly record struct AvmSystemVersion(
[property: DataMember(Name = "HW", Order = 0)] int Hw,
[property: DataMember(Name = "Major", Order = 1)] int Major,
[property: DataMember(Name = "Minor", Order = 2)] int Minor,
[property: DataMember(Name = "Patch", Order = 3)] int Patch,
[property: DataMember(Name = "Buildnumber", Order = 4)] int BuildNumber,
[property: DataMember(Name = "Display", Order = 5)] string Display);
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = UPnPConstants.Root, Namespace = UPnPConstants.Device10AvmNamespace)]
internal readonly record struct AvmUPnPDescription(
[property: DataMember(Name = "specVersion", Order = 0)] AvmSpecVersion SpecVersion,
[property: DataMember(Name = "systemVersion", Order = 1)] AvmSystemVersion SystemVersion,
[property: DataMember(Name = "device", Order = 2)] AvmDevice Device);
34 changes: 16 additions & 18 deletions RS.Fritz.Manager.API/Services/Discovery/Entities/Device.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = "device", Namespace = "urn:dslforum-org:device-1-0")]
public readonly record struct Device(
[property: DataMember(Name = "deviceType", Order = 0)] string DeviceType,
[property: DataMember(Name = "friendlyName", Order = 1)] string FriendlyName,
[property: DataMember(Name = "manufacturer", Order = 2)] string Manufacturer,
[property: DataMember(Name = "manufacturerURL", Order = 3)] string ManufacturerUrl,
[property: DataMember(Name = "modelDescription", Order = 4)] string ModelDescription,
[property: DataMember(Name = "modelName", Order = 5)] string ModelName,
[property: DataMember(Name = "modelNumber", Order = 6)] string ModelNumber,
[property: DataMember(Name = "modelURL", Order = 7)] string ModelUrl,
[property: DataMember(Name = "UDN", Order = 8)] string UniqueDeviceName,
[property: DataMember(Name = "serialNumber", Order = 9)] string SerialNumber,
[property: DataMember(Name = "UPC", Order = 10)] string Upc,
[property: DataMember(Name = "iconList", Order = 11)] IconListItem[] IconList,
[property: DataMember(Name = "serviceList", Order = 12)] ServiceListItem[] ServiceList,
[property: DataMember(Name = "deviceList", Order = 13)] Device[]? DeviceList,
[property: DataMember(Name = "presentationURL", Order = 14)] string PresentationUrl);
string DeviceType,
string FriendlyName,
string Manufacturer,
string ManufacturerUrl,
string ModelDescription,
string ModelName,
string ModelNumber,
string ModelUrl,
string UniqueDeviceName,
string? UniversalProductCode,
string? SerialNumber,
string? OriginUniqueDeviceName,
ICollection<IconListItem>? IconList,
ICollection<ServiceListItem>? ServiceList,
ICollection<Device>? DeviceList,
string? PresentationUrl);
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace RS.Fritz.Manager.API;

using System;
using System.Net;

public readonly record struct DeviceSearchResponse(
string? CacheControl,
string? Date,
string? Ext,
Uri? Location,
string? Server,
string? SearchTarget,
string? Usn,
string? Opt,
string? Nls,
int? BootId,
int? ConfigId,
ushort? SearchPort,
Uri? SecureLocation,
IPAddress IpAddress,
IPAddress LocalIpAddress);
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = "icon", Namespace = "urn:dslforum-org:device-1-0")]
public readonly record struct IconListItem(
[property: DataMember(Name = "mimetype", Order = 0)] string Mimetype,
[property: DataMember(Name = "width", Order = 1)] int Width,
[property: DataMember(Name = "height", Order = 2)] int Height,
[property: DataMember(Name = "depth", Order = 3)] int Depth,
[property: DataMember(Name = "url", Order = 4)] string Url);
public readonly record struct IconListItem(string Mimetype, int Width, int Height, int Depth, string Url);

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace RS.Fritz.Manager.API;

using System.Collections.Frozen;
using System.Net;

public readonly record struct ServerDeviceResponse(string? Server, FrozenSet<IPAddress> IpAddresses, FrozenSet<UsnDeviceResponse> UsnDeviceResponses);
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = "service", Namespace = "urn:dslforum-org:device-1-0")]
public readonly record struct ServiceListItem(
[property: DataMember(Name = "serviceType", Order = 0)] string ServiceType,
[property: DataMember(Name = "serviceId", Order = 1)] string ServiceId,
[property: DataMember(Name = "controlURL", Order = 2)] string ControlUrl,
[property: DataMember(Name = "eventSubURL", Order = 3)] string EventSubUrl,
[property: DataMember(Name = "SCPDURL", Order = 4)] string ScpdUrl);
public readonly record struct ServiceListItem(string ServiceType, string ServiceId, string ControlUrl, string EventSubUrl, string ScpdUrl);
21 changes: 21 additions & 0 deletions RS.Fritz.Manager.API/Services/Discovery/Entities/SoapDevice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = UPnPConstants.Device, Namespace = UPnPConstants.Device10Namespace)]
internal readonly record struct SoapDevice(
[property: DataMember(Name = "deviceType", Order = 0)] string DeviceType,
[property: DataMember(Name = "friendlyName", Order = 1)] string FriendlyName,
[property: DataMember(Name = "manufacturer", Order = 2)] string Manufacturer,
[property: DataMember(Name = "manufacturerURL", Order = 3)] string ManufacturerUrl,
[property: DataMember(Name = "modelDescription", Order = 4)] string ModelDescription,
[property: DataMember(Name = "modelName", Order = 5)] string ModelName,
[property: DataMember(Name = "modelNumber", Order = 6)] string ModelNumber,
[property: DataMember(Name = "modelURL", Order = 7)] string ModelUrl,
[property: DataMember(Name = "UDN", Order = 8)] string UniqueDeviceName,
[property: DataMember(Name = "UPC", Order = 9)] string? UniversalProductCode,
[property: DataMember(Name = "serialNumber", Order = 10)] string? SerialNumber,
[property: DataMember(Name = "iconList", Order = 11)] ICollection<SoapIconListItem>? IconList,
[property: DataMember(Name = "serviceList", Order = 12)] ICollection<SoapServiceListItem>? ServiceList,
[property: DataMember(Name = "deviceList", Order = 13)] ICollection<SoapDevice>? DeviceList,
[property: DataMember(Name = "presentationURL", Order = 14)] string? PresentationUrl);
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = UPnPConstants.Icon, Namespace = UPnPConstants.Device10Namespace)]
internal readonly record struct SoapIconListItem(
[property: DataMember(Name = "mimetype", Order = 0)] string Mimetype,
[property: DataMember(Name = "width", Order = 1)] int Width,
[property: DataMember(Name = "height", Order = 2)] int Height,
[property: DataMember(Name = "depth", Order = 3)] int Depth,
[property: DataMember(Name = "url", Order = 4)] string Url);
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = UPnPConstants.Service, Namespace = UPnPConstants.Device10Namespace)]
internal readonly record struct SoapServiceListItem(
[property: DataMember(Name = "serviceType", Order = 0)] string ServiceType,
[property: DataMember(Name = "serviceId", Order = 1)] string ServiceId,
[property: DataMember(Name = "controlURL", Order = 2)] string ControlUrl,
[property: DataMember(Name = "eventSubURL", Order = 3)] string EventSubUrl,
[property: DataMember(Name = "SCPDURL", Order = 4)] string ScpdUrl);
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = UPnPConstants.SpecVersion, Namespace = UPnPConstants.Device10Namespace)]
internal readonly record struct SoapSpecVersion(
[property: DataMember(Name = "major", Order = 0)] int Major,
[property: DataMember(Name = "minor", Order = 1)] int Minor);
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = UPnPConstants.Root, Namespace = UPnPConstants.Device10Namespace)]
internal readonly record struct SoapUPnPDescription(
[property: DataMember(Name = "specVersion", Order = 0)] SoapSpecVersion SpecVersion,
[property: DataMember(Name = "URLBase", Order = 1)] string? UrlBase,
[property: DataMember(Name = "device", Order = 2)] SoapDevice Device);
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = "specVersion", Namespace = "urn:dslforum-org:device-1-0")]
public readonly record struct SpecVersion(
[property: DataMember(Name = "major", Order = 0)] int Major,
[property: DataMember(Name = "minor", Order = 1)] int Minor);
public readonly record struct SpecVersion(int Major, int Minor);
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
namespace RS.Fritz.Manager.API;

using System.Runtime.Serialization;

[DataContract(Name = "systemVersion", Namespace = "urn:dslforum-org:device-1-0")]
public readonly record struct SystemVersion(
[property: DataMember(Name = "HW", Order = 0)] int Hw,
[property: DataMember(Name = "Major", Order = 1)] int Major,
[property: DataMember(Name = "Minor", Order = 2)] int Minor,
[property: DataMember(Name = "Patch", Order = 3)] int Patch,
[property: DataMember(Name = "Buildnumber", Order = 4)] int BuildNumber,
[property: DataMember(Name = "Display", Order = 5)] string Display);
public readonly record struct SystemVersion(int Hw, int Major, int Minor, int Patch, int BuildNumber, string Display);
Loading

0 comments on commit a2baf5c

Please sign in to comment.