Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions ControlApp/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

using Nefarius.DsHidMini.ControlApp.Models;
using Nefarius.DsHidMini.ControlApp.Models.DshmConfigManager;
using Nefarius.DsHidMini.ControlApp.Models.Util.Web;
using Nefarius.DsHidMini.ControlApp.Services;
using Nefarius.DsHidMini.ControlApp.ViewModels.Pages;
using Nefarius.DsHidMini.ControlApp.ViewModels.Windows;
Expand Down Expand Up @@ -60,6 +61,8 @@ public partial class App
services.AddSingleton<SettingsViewModel>();
services.AddSingleton<Main>();

services.AddSingleton<AddressValidator>();

Log.Logger = new LoggerConfiguration()
#if DEBUG
.MinimumLevel.Debug()
Expand All @@ -76,6 +79,12 @@ public partial class App
client.BaseAddress = new Uri("https://buildbot.nefarius.at/");
client.DefaultRequestHeaders.UserAgent.ParseAdd(context.HostingEnvironment.ApplicationName);
});

services.AddHttpClient("Docs", client =>
{
client.BaseAddress = new Uri("https://docs.nefarius.at/");
client.DefaultRequestHeaders.UserAgent.ParseAdd(context.HostingEnvironment.ApplicationName);
});
}).Build();

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Net.NetworkInformation;

using Newtonsoft.Json;

namespace Nefarius.DsHidMini.ControlApp.Models.Util.Web;

[SuppressMessage("ReSharper", "InconsistentNaming")]
Expand Down Expand Up @@ -54,21 +53,27 @@ public override int GetHashCode()
}
}

public class Validator
/// <summary>
/// Genuine controller MAC address validator.
/// </summary>
/// <remarks>https://github.com/nefarius/DsHidMini/discussions/166</remarks>
public sealed class AddressValidator(IHttpClientFactory clientFactory)
{
public static Uri ApiUrl => new("https://docs.nefarius.at/projects/DsHidMini/genuine_oui_db.json");

[Obsolete("Redesign to use modern HttpClient instead.")]
public static bool IsGenuineAddress(PhysicalAddress address)
public async Task<bool> IsGenuineAddress(PhysicalAddress address)
{
using (WebClient client = new())
{
IEnumerable<OUIEntry> ouiList = JsonConvert.DeserializeObject<IList<string>>(client.DownloadString(ApiUrl))
.Select(e => new OUIEntry(e));
using HttpClient client = clientFactory.CreateClient("Docs");

OUIEntry device = new(address);
IEnumerable<OUIEntry>? ouiList =
(await client.GetFromJsonAsync<IList<string>>("/projects/DsHidMini/genuine_oui_db.json"))
?.Select(e => new OUIEntry(e));

return ouiList.Contains(device);
if (ouiList is null)
{
return false;
}

OUIEntry device = new(address);

return ouiList.Contains(device);
}
}
42 changes: 31 additions & 11 deletions ControlApp/ViewModels/Pages/DevicesViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

using Nefarius.DsHidMini.ControlApp.Models;
using Nefarius.DsHidMini.ControlApp.Models.DshmConfigManager;
using Nefarius.DsHidMini.ControlApp.Models.Util.Web;
using Nefarius.DsHidMini.ControlApp.Services;
using Nefarius.DsHidMini.ControlApp.ViewModels.UserControls;
using Nefarius.Utilities.DeviceManagement.PnP;
Expand All @@ -19,6 +20,7 @@ public partial class DevicesViewModel : ObservableObject, INavigationAware
{
private readonly AppSnackbarMessagesService _appSnackbarMessagesService;
private readonly IContentDialogService _contentDialogService;
private readonly AddressValidator _addressValidator;
private readonly DshmConfigManager _dshmConfigManager;

private readonly DshmDevMan _dshmDevMan;
Expand All @@ -36,15 +38,21 @@ public partial class DevicesViewModel : ObservableObject, INavigationAware
[ObservableProperty]
private DeviceViewModel? _selectedDevice;

public DevicesViewModel(DshmDevMan dshmDevMan, DshmConfigManager dshmConfigManager,
AppSnackbarMessagesService appSnackbarMessagesService, IContentDialogService contentDialogService)
public DevicesViewModel(
DshmDevMan dshmDevMan,
DshmConfigManager dshmConfigManager,
AppSnackbarMessagesService appSnackbarMessagesService,
IContentDialogService contentDialogService,
AddressValidator addressValidator
)
{
_dshmDevMan = dshmDevMan;
_dshmConfigManager = dshmConfigManager;
_appSnackbarMessagesService = appSnackbarMessagesService;
_dshmDevMan.ConnectedDeviceListUpdated += OnConnectedDevicesListUpdated;
_dshmConfigManager.DshmConfigurationUpdated += OnDshmConfigUpdated;
_contentDialogService = contentDialogService;
_addressValidator = addressValidator;
RefreshDevicesList();
}

Expand All @@ -59,16 +67,14 @@ public DevicesViewModel(DshmDevMan dshmDevMan, DshmConfigManager dshmConfigManag
/// </summary>
public bool HasDeviceSelected => SelectedDevice != null;

public Task OnNavigatedToAsync()
public async Task OnNavigatedToAsync()
{
Log.Logger.Debug(
"Navigating to Devices page. Refreshing dynamic properties of each connected Device ViewModel.");
foreach (DeviceViewModel device in Devices)
{
device.RefreshDeviceSettings();
await device.RefreshDeviceSettings();
}

return Task.CompletedTask;
}

public Task OnNavigatedFromAsync()
Expand Down Expand Up @@ -173,13 +179,27 @@ Reconnect the pending devices to make this change effective.

private void RefreshDevicesList()
{
App.Current.Dispatcher.BeginInvoke(new Action(() =>
Application.Current.Dispatcher.BeginInvoke(new Action(async void () =>
{
Devices.Clear();
foreach (PnPDevice device in _dshmDevMan.Devices)
try
{
Devices.Clear();
foreach (DeviceViewModel newDev in _dshmDevMan.Devices.Select(device => new DeviceViewModel(
device,
_dshmDevMan,
_dshmConfigManager,
_appSnackbarMessagesService,
_contentDialogService,
_addressValidator
)))
{
Devices.Add(newDev);
await newDev.RefreshDeviceSettings();
}
}
catch (Exception e)
{
Devices.Add(new DeviceViewModel(device, _dshmDevMan, _dshmConfigManager, _appSnackbarMessagesService,
_contentDialogService));
Log.Logger.Error(e, "Error refreshing devices list");
}
}));
}
Expand Down
49 changes: 33 additions & 16 deletions ControlApp/ViewModels/UserControls/DeviceViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System.Text.RegularExpressions;
using System.Net.NetworkInformation;
using System.Text.RegularExpressions;

using Nefarius.DsHidMini.ControlApp.Models;
using Nefarius.DsHidMini.ControlApp.Models.DshmConfigManager;
using Nefarius.DsHidMini.ControlApp.Models.DshmConfigManager.Enums;
using Nefarius.DsHidMini.ControlApp.Models.Enums;
using Nefarius.DsHidMini.ControlApp.Models.Util.Web;
using Nefarius.DsHidMini.ControlApp.Services;
using Nefarius.DsHidMini.IPC.Models.Drivers;
using Nefarius.Utilities.DeviceManagement.PnP;
Expand All @@ -19,6 +21,7 @@ public partial class DeviceViewModel : ObservableObject
private readonly AppSnackbarMessagesService _appSnackbarMessagesService;
private readonly Timer _batteryQuery;
private readonly IContentDialogService _contentDialogService;
private readonly AddressValidator _addressValidator;

private readonly DeviceData _deviceUserData;

Expand Down Expand Up @@ -77,6 +80,12 @@ public partial class DeviceViewModel : ObservableObject
/// </summary>
private BluetoothPairingMode? _pairingMode;

/// <summary>
/// Whether the controller is deemed official Sony genuine by using the online address database.
/// </summary>
[ObservableProperty]
private bool _isGenuine;


// ------------------------------------------------------ METHODS

Expand All @@ -86,22 +95,28 @@ public partial class DeviceViewModel : ObservableObject

// ------------------------------------------------------ CONSTRUCTOR

internal DeviceViewModel(PnPDevice device, DshmDevMan dshmDevMan, DshmConfigManager dshmConfigManager,
AppSnackbarMessagesService appSnackbarMessagesService, IContentDialogService contentDialogService)
internal DeviceViewModel(
PnPDevice device,
DshmDevMan dshmDevMan,
DshmConfigManager dshmConfigManager,
AppSnackbarMessagesService appSnackbarMessagesService,
IContentDialogService contentDialogService,
AddressValidator addressValidator
)
{
Device = device;
Log.Logger.Debug($"Creating Device ViewModel for device '{DeviceAddress}'");
Log.Logger.Debug("Creating Device ViewModel for device '{S}'", DeviceAddress);
_dshmDevMan = dshmDevMan;
_dshmConfigManager = dshmConfigManager;
_appSnackbarMessagesService = appSnackbarMessagesService;
_contentDialogService = contentDialogService;
_addressValidator = addressValidator;
_batteryQuery = new Timer(UpdateBatteryStatus, null, 10000, 10000);
_deviceUserData = _dshmConfigManager.GetDeviceData(DeviceAddress);
// Loads correspondent controller data based on controller's MAC address


//DisplayName = DeviceAddress;
RefreshDeviceSettings();
}

public PnPDevice Device { get; }
Expand All @@ -123,7 +138,7 @@ internal DeviceViewModel(PnPDevice device, DshmDevMan dshmDevMan, DshmConfigMana
/// <summary>
/// State of Device's current HID Mode in relation to mode it's expected to be
/// </summary>
public bool IsHidModeMismatched => HidEmulationMode != ExpectedHidMode ? true : false;
public bool IsHidModeMismatched => HidEmulationMode != ExpectedHidMode;

/// <summary>
/// Summary of device's current HID mode and Settings mode
Expand Down Expand Up @@ -249,12 +264,12 @@ public string? CustomPairingAddress
/// <summary>
/// Index of the desired Bluetooth pairing mode
/// </summary>
public int PairingMode
public BluetoothPairingMode PairingMode
{
get => (int)_pairingMode;
get => _pairingMode ?? BluetoothPairingMode.Auto;
set
{
_pairingMode = (BluetoothPairingMode)value;
_pairingMode = value;
OnPropertyChanged();
}
}
Expand Down Expand Up @@ -384,11 +399,11 @@ private void AdjustSettingsTabState()
}

[RelayCommand]
public void RefreshDeviceSettings()
public async Task RefreshDeviceSettings()
{
Log.Logger.Debug("Refreshing ViewModel of Device '{Address}'", DeviceAddress);
// Bluetooth
PairingMode = (int)_deviceUserData.BluetoothPairingMode;
PairingMode = _deviceUserData.BluetoothPairingMode;
CustomPairingAddress = _deviceUserData.PairingAddress;

// Settings and selected profile
Expand All @@ -398,22 +413,24 @@ public void RefreshDeviceSettings()

Log.Logger.Information(
"Device '{S}' set for {SettingsContext} HID Mode (currently in {HidModeShort1}), {BluetoothPairingMode} Bluetooth pairing mode."
, DeviceAddress, ExpectedHidMode, HidModeShort, (BluetoothPairingMode)PairingMode);
if ((BluetoothPairingMode)PairingMode == BluetoothPairingMode.Custom)
, DeviceAddress, ExpectedHidMode, HidModeShort, PairingMode);
if (PairingMode == BluetoothPairingMode.Custom)
{
Log.Logger.Information("Custom pairing address: {CustomPairingAddress}.", CustomPairingAddress);
}

IsGenuine = await _addressValidator.IsGenuineAddress(PhysicalAddress.Parse(DeviceAddress));

AdjustSettingsTabState();
OnPropertyChanged(nameof(DeviceSettingsStatus));
OnPropertyChanged(nameof(IsHidModeMismatched));
}

[RelayCommand]
private void ApplyChanges()
private async Task ApplyChanges()
{
Log.Logger.Information("Saving and applying changes made to Device '{DeviceAddress}'", DeviceAddress);
_deviceUserData.BluetoothPairingMode = (BluetoothPairingMode)PairingMode;
_deviceUserData.BluetoothPairingMode = PairingMode;

string formattedCustomMacAddress = Regex.Replace(CustomPairingAddress, @"[^a-fA-F0-9]", "").ToUpper();
if (formattedCustomMacAddress.Length > 12)
Expand All @@ -436,7 +453,7 @@ private void ApplyChanges()

_dshmConfigManager.SaveChangesAndUpdateDsHidMiniConfigFile();
_appSnackbarMessagesService.ShowDsHidMiniConfigurationUpdateSuccessMessage();
RefreshDeviceSettings();
await RefreshDeviceSettings();
}

[RelayCommand]
Expand Down