implemented evaluation of ip addresses
This commit is contained in:
parent
b393146e58
commit
cf924f7b2a
13
.idea/.idea.SddpViewer/.idea/.gitignore
generated
vendored
Normal file
13
.idea/.idea.SddpViewer/.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Rider ignored files
|
||||||
|
/modules.xml
|
||||||
|
/projectSettingsUpdater.xml
|
||||||
|
/.idea.SddpViewer.iml
|
||||||
|
/contentModel.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
10
.idea/.idea.SddpViewer/.idea/avalonia.xml
generated
Normal file
10
.idea/.idea.SddpViewer/.idea/avalonia.xml
generated
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AvaloniaProject">
|
||||||
|
<option name="projectPerEditor">
|
||||||
|
<map>
|
||||||
|
<entry key="MainWindow.axaml" value="SddpViewer.csproj" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
4
.idea/.idea.SddpViewer/.idea/encodings.xml
generated
Normal file
4
.idea/.idea.SddpViewer/.idea/encodings.xml
generated
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
||||||
|
</project>
|
8
.idea/.idea.SddpViewer/.idea/indexLayout.xml
generated
Normal file
8
.idea/.idea.SddpViewer/.idea/indexLayout.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="UserContentModel">
|
||||||
|
<attachedFolders />
|
||||||
|
<explicitIncludes />
|
||||||
|
<explicitExcludes />
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/.idea.SddpViewer/.idea/vcs.xml
generated
Normal file
6
.idea/.idea.SddpViewer/.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -1,53 +1,53 @@
|
|||||||
namespace SddpViewer
|
namespace SddpViewer
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
using Rssdp;
|
using Rssdp;
|
||||||
|
|
||||||
public partial class DiscoveredDeviceViewModel : ObservableObject
|
public partial class DiscoveredDeviceViewModel : ObservableObject
|
||||||
{
|
|
||||||
private readonly DiscoveredSsdpDevice device;
|
|
||||||
|
|
||||||
public DiscoveredDeviceViewModel(DiscoveredSsdpDevice device)
|
|
||||||
{
|
{
|
||||||
this.device = device;
|
private readonly DiscoveredSsdpDevice device;
|
||||||
|
|
||||||
|
public DiscoveredDeviceViewModel(DiscoveredSsdpDevice device)
|
||||||
|
{
|
||||||
|
this.device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets or returns the type of notification, being either a uuid, device type, service type or upnp:rootdevice.
|
||||||
|
/// </summary>
|
||||||
|
public string NotificationType => this.device.NotificationType;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets or returns the universal service name (USN) of the device.
|
||||||
|
/// </summary>
|
||||||
|
public string Usn => this.device.Usn;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets or returns a URL pointing to the device description document for this device.
|
||||||
|
/// </summary>
|
||||||
|
public Uri DescriptionLocation => this.device.DescriptionLocation;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets or returns the length of time this information is valid for (from the <see cref="P:Rssdp.DiscoveredSsdpDevice.AsAt" /> time).
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan CacheLifetime => this.device.CacheLifetime;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets or returns the date and time this information was received.
|
||||||
|
/// </summary>
|
||||||
|
public DateTimeOffset AsAt => this.device.AsAt;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _friendlyName = "";
|
||||||
|
|
||||||
|
public async Task GetFurtherInformationAsync()
|
||||||
|
{
|
||||||
|
var ssdpDevice = await this.device.GetDeviceInfo().ConfigureAwait(false);
|
||||||
|
FriendlyName = ssdpDevice.FriendlyName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets or returns the type of notification, being either a uuid, device type, service type or upnp:rootdevice.
|
|
||||||
/// </summary>
|
|
||||||
public string NotificationType => this.device.NotificationType;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets or returns the universal service name (USN) of the device.
|
|
||||||
/// </summary>
|
|
||||||
public string Usn => this.device.Usn;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets or returns a URL pointing to the device description document for this device.
|
|
||||||
/// </summary>
|
|
||||||
public Uri DescriptionLocation => this.device.DescriptionLocation;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets or returns the length of time this information is valid for (from the <see cref="P:Rssdp.DiscoveredSsdpDevice.AsAt" /> time).
|
|
||||||
/// </summary>
|
|
||||||
public TimeSpan CacheLifetime => this.device.CacheLifetime;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets or returns the date and time this information was received.
|
|
||||||
/// </summary>
|
|
||||||
public DateTimeOffset AsAt => this.device.AsAt;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string _friendlyName = "";
|
|
||||||
|
|
||||||
public async Task GetFurtherInformationAsync()
|
|
||||||
{
|
|
||||||
var ssdpDevice = await this.device.GetDeviceInfo().ConfigureAwait(false);
|
|
||||||
FriendlyName = ssdpDevice.FriendlyName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,35 +1,34 @@
|
|||||||
<Window
|
<Window
|
||||||
x:Class="SddpViewer.MainWindow"
|
|
||||||
xmlns="https://github.com/avaloniaui"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:sddpViewer="clr-namespace:SddpViewer"
|
|
||||||
Title="SDDP viewer"
|
Title="SDDP viewer"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
d:DesignWidth="800"
|
d:DesignWidth="800"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
x:Class="SddpViewer.MainWindow"
|
||||||
x:CompileBindings="True"
|
x:CompileBindings="True"
|
||||||
x:DataType="sddpViewer:MainWindowViewModel"
|
x:DataType="sddpViewer:MainWindowViewModel"
|
||||||
mc:Ignorable="d">
|
xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:sddpViewer="clr-namespace:SddpViewer"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
<Window.DataContext>
|
<Window.DataContext>
|
||||||
<sddpViewer:MainWindowViewModel />
|
<sddpViewer:MainWindowViewModel />
|
||||||
</Window.DataContext>
|
</Window.DataContext>
|
||||||
<Grid RowDefinitions="Auto, *">
|
<Grid RowDefinitions="Auto, *">
|
||||||
<StackPanel Margin="10" Spacing="5">
|
<StackPanel Margin="10" Spacing="5">
|
||||||
<TextBlock Text="Settings" />
|
<TextBlock Text="Device IP Address" />
|
||||||
<TextBox
|
<ComboBox
|
||||||
Text="{Binding DeviceIpAddress}"
|
DisplayMemberBinding="{Binding DisplayName}"
|
||||||
UseFloatingWatermark="True"
|
HorizontalAlignment="Stretch"
|
||||||
Watermark="Device IP Address" />
|
ItemsSource="{Binding NetworkAdapters}"
|
||||||
<TextBox
|
SelectedItem="{Binding SelectedNetworkAdapter}" />
|
||||||
Text="{Binding NotificationFilter}"
|
<TextBlock Text="Notification filter" />
|
||||||
UseFloatingWatermark="True"
|
<TextBox Text="{Binding NotificationFilter}" />
|
||||||
Watermark="Notification filter" />
|
|
||||||
<Button Command="{Binding SearchDevicesNowCommand}" Content="Search now" />
|
<Button Command="{Binding SearchDevicesNowCommand}" Content="Search now" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<DataGrid
|
<DataGrid
|
||||||
Grid.Row="1"
|
|
||||||
AutoGenerateColumns="True"
|
AutoGenerateColumns="True"
|
||||||
|
Grid.Row="1"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
ItemsSource="{Binding SddpDevices}" />
|
ItemsSource="{Binding SddpDevices}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
namespace SddpViewer;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
namespace SddpViewer;
|
||||||
|
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -10,35 +16,53 @@ using Rssdp;
|
|||||||
|
|
||||||
public partial class MainWindowViewModel : ObservableObject
|
public partial class MainWindowViewModel : ObservableObject
|
||||||
{
|
{
|
||||||
[ObservableProperty]
|
public MainWindowViewModel()
|
||||||
private string _deviceIpAddress = "192.168.42.193";
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string _notificationFilter = "upnp:rootdevice";
|
|
||||||
|
|
||||||
public ObservableCollection<DiscoveredDeviceViewModel> SddpDevices { get; } = new();
|
|
||||||
|
|
||||||
[RelayCommand(AllowConcurrentExecutions = false)]
|
|
||||||
private async Task SearchDevicesNowAsync()
|
|
||||||
{
|
|
||||||
SddpDevices.Clear();
|
|
||||||
var locator = new SsdpDeviceLocator(DeviceIpAddress);
|
|
||||||
if (!string.IsNullOrWhiteSpace(NotificationFilter))
|
|
||||||
{
|
{
|
||||||
locator.NotificationFilter = NotificationFilter;
|
NetworkAdapters = NetworkAdapter.GetAvailableNetworkAdapter().ToArray();
|
||||||
|
SelectedNetworkAdapter = NetworkAdapters.FirstOrDefault();
|
||||||
}
|
}
|
||||||
var availableDevices = await locator.SearchAsync().ConfigureAwait(true);
|
|
||||||
foreach (var ssdpDevice in availableDevices)
|
[ObservableProperty]
|
||||||
|
private IReadOnlyList<NetworkAdapter> _networkAdapters;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private NetworkAdapter? _selectedNetworkAdapter;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _deviceIpAddress = "192.168.42.193";
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _notificationFilter = "upnp:rootdevice";
|
||||||
|
|
||||||
|
public ObservableCollection<DiscoveredDeviceViewModel> SddpDevices { get; } = new();
|
||||||
|
|
||||||
|
[RelayCommand(AllowConcurrentExecutions = false)]
|
||||||
|
private async Task SearchDevicesNowAsync()
|
||||||
{
|
{
|
||||||
var discoveredDeviceViewModel = new DiscoveredDeviceViewModel(ssdpDevice);
|
SddpDevices.Clear();
|
||||||
SddpDevices.Add(discoveredDeviceViewModel);
|
if (SelectedNetworkAdapter is null)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
var locator = new SsdpDeviceLocator(SelectedNetworkAdapter.IpAddress.ToString());
|
||||||
|
if (!string.IsNullOrWhiteSpace(NotificationFilter))
|
||||||
|
{
|
||||||
|
locator.NotificationFilter = NotificationFilter;
|
||||||
|
}
|
||||||
|
var availableDevices = await locator.SearchAsync().ConfigureAwait(true);
|
||||||
|
foreach (var ssdpDevice in availableDevices)
|
||||||
|
{
|
||||||
|
var discoveredDeviceViewModel = new DiscoveredDeviceViewModel(ssdpDevice);
|
||||||
|
SddpDevices.Add(discoveredDeviceViewModel);
|
||||||
|
}
|
||||||
|
await Parallel
|
||||||
|
.ForEachAsync(
|
||||||
|
SddpDevices,
|
||||||
|
async (device, token) =>
|
||||||
|
{
|
||||||
|
await device.GetFurtherInformationAsync().ConfigureAwait(true);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.ConfigureAwait(true);
|
||||||
}
|
}
|
||||||
await Parallel.ForEachAsync(
|
|
||||||
SddpDevices,
|
|
||||||
async (device, token) =>
|
|
||||||
{
|
|
||||||
await device.GetFurtherInformationAsync().ConfigureAwait(true);
|
|
||||||
}
|
|
||||||
).ConfigureAwait(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
31
NetworkAdapter.cs
Normal file
31
NetworkAdapter.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
namespace SddpViewer;
|
||||||
|
|
||||||
|
public record NetworkAdapter(string Name, IPAddress IpAddress)
|
||||||
|
{
|
||||||
|
public string DisplayName => $"{Name} - {IpAddress}";
|
||||||
|
|
||||||
|
public static IEnumerable<NetworkAdapter> GetAvailableNetworkAdapter()
|
||||||
|
{
|
||||||
|
foreach (var nic in NetworkInterface.GetAllNetworkInterfaces())
|
||||||
|
{
|
||||||
|
if (nic.OperationalStatus != OperationalStatus.Up)
|
||||||
|
continue;
|
||||||
|
if (nic.NetworkInterfaceType == NetworkInterfaceType.Loopback)
|
||||||
|
continue;
|
||||||
|
var physicalAddress = nic.GetIPProperties()
|
||||||
|
.UnicastAddresses.FirstOrDefault(
|
||||||
|
x => x.Address.AddressFamily == AddressFamily.InterNetwork
|
||||||
|
);
|
||||||
|
if (physicalAddress is not null)
|
||||||
|
{
|
||||||
|
yield return new NetworkAdapter(nic.Name, physicalAddress.Address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Program.cs
11
Program.cs
@ -9,13 +9,10 @@ class Program
|
|||||||
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||||
// yet and stuff might break.
|
// yet and stuff might break.
|
||||||
[STAThread]
|
[STAThread]
|
||||||
public static void Main(string[] args) => BuildAvaloniaApp()
|
public static void Main(string[] args) =>
|
||||||
.StartWithClassicDesktopLifetime(args);
|
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
|
||||||
|
|
||||||
// Avalonia configuration, don't remove; also used by visual designer.
|
// Avalonia configuration, don't remove; also used by visual designer.
|
||||||
public static AppBuilder BuildAvaloniaApp()
|
public static AppBuilder BuildAvaloniaApp() =>
|
||||||
=> AppBuilder.Configure<App>()
|
AppBuilder.Configure<App>().UsePlatformDetect().WithInterFont().LogToTrace();
|
||||||
.UsePlatformDetect()
|
|
||||||
.WithInterFont()
|
|
||||||
.LogToTrace();
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user