From 0e158115b6958efc75dcfd7a2c56e6583dfa6479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ayta=C3=A7=20Kayadelen?= Date: Sun, 18 Jun 2023 23:28:38 +0200 Subject: [PATCH 1/6] implement DeviceConnection event for Corsair and make name creations consistent --- .../Devices/AbstractRGBDeviceProvider.cs | 2 + .../CorsairDeviceProvider.cs | 324 ++++++++++-------- .../Enum/CorsairEventId.cs | 8 + .../Generic/CorsairRGBDevice.cs | 25 +- .../Generic/CorsairRGBDeviceInfo.cs | 31 +- .../Generic/ICorsairRGBDevice.cs | 2 + RGB.NET.Devices.Corsair/Native/_CUESDK.cs | 61 +++- ...rsairDeviceConnectionStatusChangedEvent.cs | 19 + .../Native/_CorsairDeviceInfo.cs | 2 +- .../Native/_CorsairEvent.cs | 22 ++ 10 files changed, 337 insertions(+), 159 deletions(-) create mode 100644 RGB.NET.Devices.Corsair/Enum/CorsairEventId.cs create mode 100644 RGB.NET.Devices.Corsair/Native/_CorsairDeviceConnectionStatusChangedEvent.cs create mode 100644 RGB.NET.Devices.Corsair/Native/_CorsairEvent.cs diff --git a/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs index e76554e1..ebcc6273 100644 --- a/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs +++ b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using System.Runtime.CompilerServices; namespace RGB.NET.Core; @@ -150,6 +151,7 @@ protected virtual IEnumerable GetLoadedDevices(RGBDeviceType loadFil /// The id of the update trigger. /// The update rate hard limit to be set in the update trigger. /// The update trigger mapped to the specified id. + [MethodImpl(MethodImplOptions.Synchronized)] protected virtual IDeviceUpdateTrigger GetUpdateTrigger(int id = -1, double? updateRateHardLimit = null) { if (!UpdateTriggerMapping.TryGetValue(id, out IDeviceUpdateTrigger? updaeTrigger)) diff --git a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs index 87ab725e..f8c68b2f 100644 --- a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs +++ b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using RGB.NET.Core; using RGB.NET.Devices.Corsair.Native; @@ -111,19 +112,50 @@ void OnInitializeSessionStateChanged(object? sender, CorsairSessionState state) Throw(new RGBDeviceException($"Failed to initialized Corsair-SDK. (ErrorCode: {errorCode})")); if (!waitEvent.Wait(ConnectionTimeout)) - Throw(new RGBDeviceException($"Failed to initialized Corsair-SDK. (Timeout - Current connection state: {_CUESDK.SesionState})")); + Throw(new RGBDeviceException($"Failed to initialized Corsair-SDK. (Timeout - Current connection state: {_CUESDK.SessionState})")); _CUESDK.CorsairGetSessionDetails(out _CorsairSessionDetails? details); if (errorCode != CorsairError.Success) Throw(new RGBDeviceException($"Failed to get session details. (ErrorCode: {errorCode})")); SessionDetails = new CorsairSessionDetails(details!); + _CUESDK.DeviceConnectionEvent += OnDeviceConnectionEvent; } finally { _CUESDK.SessionStateChanged -= OnInitializeSessionStateChanged; } } + + private void OnDeviceConnectionEvent(object? sender, _CorsairDeviceConnectionStatusChangedEvent connectionStatusChangedEvent) + { + string? deviceId = connectionStatusChangedEvent.deviceId; + if (string.IsNullOrWhiteSpace(deviceId)) return; + if (connectionStatusChangedEvent.isConnected) + { + _CUESDK.CorsairGetDeviceInfo(deviceId, out _CorsairDeviceInfo deviceInfo); + IDeviceUpdateTrigger deviceUpdateTrigger = GetUpdateTrigger(); + IEnumerable device = LoadDevice(deviceInfo, deviceUpdateTrigger); + foreach (ICorsairRGBDevice corsairRGBDevice in device) + { + corsairRGBDevice.Initialize(); + if (!AddDevice(corsairRGBDevice)) + { + deviceUpdateTrigger.Dispose(); + } + else + { + deviceUpdateTrigger.Start(); + } + } + } + else + { + IRGBDevice? removedDevice = Devices.FirstOrDefault(device => ((ICorsairRGBDevice)device).DeviceId == deviceId); + if (removedDevice == null) return; + RemoveDevice(removedDevice); //TODO disposing the device disposes device queue! + } + } private void OnSessionStateChanged(object? sender, CorsairSessionState state) => SessionState = state; @@ -143,162 +175,166 @@ private IEnumerable LoadCorsairDevices() if (error != CorsairError.Success) Throw(new RGBDeviceException($"Failed to load devices. (ErrorCode: {error})")); - foreach (_CorsairDeviceInfo device in devices) + return devices.SelectMany(LoadDevice); + } + + private IEnumerable LoadDevice(_CorsairDeviceInfo device) + { + return LoadDevice(device, GetUpdateTrigger()); + } + + private IEnumerable LoadDevice(_CorsairDeviceInfo device, IDeviceUpdateTrigger updateTrigger) + { + if (string.IsNullOrWhiteSpace(device.id)) yield break; + + // sometimes it is okay to fail :) (can cause problems with reconnections) + _CUESDK.CorsairRequestControl(device.id, ExclusiveAccess ? CorsairAccessLevel.ExclusiveLightingControl : CorsairAccessLevel.Shared); + + CorsairDeviceUpdateQueue updateQueue = new(updateTrigger, device); + + int channelLedCount = 0; + for (int i = 0; i < device.channelCount; i++) { - if (string.IsNullOrWhiteSpace(device.id)) continue; + Console.WriteLine($"Channel {i}/{device.channelCount}"); + channelLedCount += _CUESDK.ReadDevicePropertySimpleInt32(device.id!, CorsairDevicePropertyId.ChannelLedCount, (uint)i); + } - error = _CUESDK.CorsairRequestControl(device.id, ExclusiveAccess ? CorsairAccessLevel.ExclusiveLightingControl : CorsairAccessLevel.Shared); - if (error != CorsairError.Success) - Throw(new RGBDeviceException($"Failed to take control of device '{device.id}'. (ErrorCode: {error})")); + int deviceLedCount = device.ledCount - channelLedCount; + if (deviceLedCount > 0) + { + ICorsairRGBDevice singleChannelDevice = CreateSingleChannelDevice(device, deviceLedCount, updateQueue); + yield return singleChannelDevice; + } - CorsairDeviceUpdateQueue updateQueue = new(GetUpdateTrigger(), device); - int channelLedCount = 0; - for (int i = 0; i < device.channelCount; i++) - { - Console.WriteLine($"Channel {i}/{device.channelCount}"); - channelLedCount += _CUESDK.ReadDevicePropertySimpleInt32(device.id!, CorsairDevicePropertyId.ChannelLedCount, (uint)i); - } + int offset = deviceLedCount; + for (int i = 0; i < device.channelCount; i++) + { + int deviceCount = _CUESDK.ReadDevicePropertySimpleInt32(device.id!, CorsairDevicePropertyId.ChannelDeviceCount, (uint)i); + if (deviceCount <= 0) + continue; // DarthAffe 10.02.2023: There seem to be an issue in the SDK where it reports empty channels and fails + // when getting ledCounts and device types from them - int deviceLedCount = device.ledCount - channelLedCount; - if (deviceLedCount > 0) - switch (device.type) - { - case CorsairDeviceType.Keyboard: - yield return new CorsairKeyboardRGBDevice(new CorsairKeyboardRGBDeviceInfo(device, deviceLedCount, 0), updateQueue); - break; - - case CorsairDeviceType.Mouse: - yield return new CorsairMouseRGBDevice(new CorsairMouseRGBDeviceInfo(device, deviceLedCount, 0), updateQueue); - break; - - case CorsairDeviceType.Headset: - yield return new CorsairHeadsetRGBDevice(new CorsairHeadsetRGBDeviceInfo(device, deviceLedCount, 0), updateQueue); - break; - - case CorsairDeviceType.Mousemat: - yield return new CorsairMousepadRGBDevice(new CorsairMousepadRGBDeviceInfo(device, deviceLedCount, 0), updateQueue); - break; - - case CorsairDeviceType.HeadsetStand: - yield return new CorsairHeadsetStandRGBDevice(new CorsairHeadsetStandRGBDeviceInfo(device, deviceLedCount, 0), updateQueue); - break; - - case CorsairDeviceType.MemoryModule: - yield return new CorsairMemoryRGBDevice(new CorsairMemoryRGBDeviceInfo(device, deviceLedCount, 0), updateQueue); - break; - - case CorsairDeviceType.Motherboard: - yield return new CorsairMainboardRGBDevice(new CorsairMainboardRGBDeviceInfo(device, deviceLedCount, 0), updateQueue); - break; - - case CorsairDeviceType.GraphicsCard: - yield return new CorsairGraphicsCardRGBDevice(new CorsairGraphicsCardRGBDeviceInfo(device, deviceLedCount, 0), updateQueue); - break; - - case CorsairDeviceType.Touchbar: - yield return new CorsairTouchbarRGBDevice(new CorsairTouchbarRGBDeviceInfo(device, deviceLedCount, 0), updateQueue); - break; - - case CorsairDeviceType.Cooler: - yield return new CorsairCoolerRGBDevice(new CorsairCoolerRGBDeviceInfo(device, deviceLedCount, 0), updateQueue); - break; - - case CorsairDeviceType.FanLedController: - case CorsairDeviceType.LedController: - case CorsairDeviceType.Unknown: - yield return new CorsairUnknownRGBDevice(new CorsairUnknownRGBDeviceInfo(device, deviceLedCount, 0), updateQueue); - break; - - default: - Throw(new RGBDeviceException("Unknown Device-Type")); - break; - } + int[] ledCounts = + _CUESDK.ReadDevicePropertySimpleInt32Array(device.id!, CorsairDevicePropertyId.ChannelDeviceLedCountArray, (uint)i); + int[] deviceTypes = _CUESDK.ReadDevicePropertySimpleInt32Array(device.id!, CorsairDevicePropertyId.ChannelDeviceTypeArray, (uint)i); - int offset = deviceLedCount; - for (int i = 0; i < device.channelCount; i++) + for (int j = 0; j < deviceCount; j++) { - int deviceCount = _CUESDK.ReadDevicePropertySimpleInt32(device.id!, CorsairDevicePropertyId.ChannelDeviceCount, (uint)i); - if (deviceCount <= 0) continue; // DarthAffe 10.02.2023: There seem to be an issue in the SDK where it reports empty channels and fails when getting ledCounts and device types from them + CorsairChannelDeviceType deviceType = (CorsairChannelDeviceType)deviceTypes[j]; + int ledCount = ledCounts[j]; - int[] ledCounts = _CUESDK.ReadDevicePropertySimpleInt32Array(device.id!, CorsairDevicePropertyId.ChannelDeviceLedCountArray, (uint)i); - int[] deviceTypes = _CUESDK.ReadDevicePropertySimpleInt32Array(device.id!, CorsairDevicePropertyId.ChannelDeviceTypeArray, (uint)i); + yield return CreateCorsairDeviceChannel(device, deviceType, ledCount, offset, updateQueue); - for (int j = 0; j < deviceCount; j++) - { - CorsairChannelDeviceType deviceType = (CorsairChannelDeviceType)deviceTypes[j]; - int ledCount = ledCounts[j]; - - switch (deviceType) - { - case CorsairChannelDeviceType.FanHD: - yield return new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "HD Fan"), updateQueue); - break; - - case CorsairChannelDeviceType.FanSP: - yield return new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "SP Fan"), updateQueue); - break; - - case CorsairChannelDeviceType.FanLL: - yield return new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "LL Fan"), updateQueue); - break; - - case CorsairChannelDeviceType.FanML: - yield return new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "ML Fan"), updateQueue); - break; - - case CorsairChannelDeviceType.FanQL: - yield return new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "QL Fan"), updateQueue); - break; - - case CorsairChannelDeviceType.EightLedSeriesFan: - yield return new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "8-Led-Series Fan Fan"), updateQueue); - break; - - case CorsairChannelDeviceType.DAP: - yield return new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "DAP Fan"), updateQueue); - break; - - case CorsairChannelDeviceType.Pump: - yield return new CorsairCoolerRGBDevice(new CorsairCoolerRGBDeviceInfo(device, ledCount, offset, "Pump"), updateQueue); - break; - - case CorsairChannelDeviceType.WaterBlock: - yield return new CorsairCoolerRGBDevice(new CorsairCoolerRGBDeviceInfo(device, ledCount, offset, "Water Block"), updateQueue); - break; - - case CorsairChannelDeviceType.Strip: - string modelName = "LED Strip"; - - // LS100 Led Strips are reported as one big strip if configured in monitor mode in iCUE, 138 LEDs for dual monitor, 84 for single - if ((device.model == "LS100 Starter Kit") && (ledCount == 138)) - modelName = "LS100 LED Strip (dual monitor)"; - else if ((device.model == "LS100 Starter Kit") && (ledCount == 84)) - modelName = "LS100 LED Strip (single monitor)"; - // Any other value means an "External LED Strip" in iCUE, these are reported per-strip, 15 for short strips, 27 for long - else if ((device.model == "LS100 Starter Kit") && (ledCount == 15)) - modelName = "LS100 LED Strip (short)"; - else if ((device.model == "LS100 Starter Kit") && (ledCount == 27)) - modelName = "LS100 LED Strip (long)"; - - yield return new CorsairLedStripRGBDevice(new CorsairLedStripRGBDeviceInfo(device, ledCount, offset, modelName), updateQueue); - break; - - case CorsairChannelDeviceType.DRAM: - yield return new CorsairMemoryRGBDevice(new CorsairMemoryRGBDeviceInfo(device, ledCount, offset, "DRAM"), updateQueue); - break; - - default: - Throw(new RGBDeviceException("Unknown Device-Type")); - break; - } - - offset += ledCount; - } + offset += ledCount; } } } + private static ICorsairRGBDevice CreateSingleChannelDevice(_CorsairDeviceInfo device, int deviceLedCount, CorsairDeviceUpdateQueue updateQueue) + { + return device.type switch + { + CorsairDeviceType.Keyboard => + new CorsairKeyboardRGBDevice(new CorsairKeyboardRGBDeviceInfo(device, deviceLedCount, 0), updateQueue), + + CorsairDeviceType.Mouse => + new CorsairMouseRGBDevice(new CorsairMouseRGBDeviceInfo(device, deviceLedCount, 0), updateQueue), + + CorsairDeviceType.Headset => + new CorsairHeadsetRGBDevice(new CorsairHeadsetRGBDeviceInfo(device, deviceLedCount, 0), updateQueue), + + CorsairDeviceType.Mousemat => + new CorsairMousepadRGBDevice(new CorsairMousepadRGBDeviceInfo(device, deviceLedCount, 0), updateQueue), + + CorsairDeviceType.HeadsetStand => + new CorsairHeadsetStandRGBDevice(new CorsairHeadsetStandRGBDeviceInfo(device, deviceLedCount, 0), updateQueue), + + CorsairDeviceType.MemoryModule => + new CorsairMemoryRGBDevice(new CorsairMemoryRGBDeviceInfo(device, deviceLedCount, 0), updateQueue), + + CorsairDeviceType.Motherboard => + new CorsairMainboardRGBDevice(new CorsairMainboardRGBDeviceInfo(device, deviceLedCount, 0), updateQueue), + + CorsairDeviceType.GraphicsCard => + new CorsairGraphicsCardRGBDevice(new CorsairGraphicsCardRGBDeviceInfo(device, deviceLedCount, 0), updateQueue), + + CorsairDeviceType.Touchbar => + new CorsairTouchbarRGBDevice(new CorsairTouchbarRGBDeviceInfo(device, deviceLedCount, 0), updateQueue), + + CorsairDeviceType.Cooler => + new CorsairCoolerRGBDevice(new CorsairCoolerRGBDeviceInfo(device, deviceLedCount, 0), updateQueue), + + CorsairDeviceType.FanLedController or + CorsairDeviceType.LedController or + CorsairDeviceType.Unknown => + new CorsairUnknownRGBDevice(new CorsairUnknownRGBDeviceInfo(device, deviceLedCount, 0), updateQueue), + + _ => throw new RGBDeviceException("Unknown Device-Type") + }; + } + + private static ICorsairRGBDevice CreateCorsairDeviceChannel(_CorsairDeviceInfo device, CorsairChannelDeviceType deviceType, + int ledCount, int offset, CorsairDeviceUpdateQueue updateQueue) + { + return deviceType switch + { + CorsairChannelDeviceType.FanHD => + new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "HD Fan"), updateQueue), + + CorsairChannelDeviceType.FanSP => + new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "SP Fan"), updateQueue), + + CorsairChannelDeviceType.FanLL => + new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "LL Fan"), updateQueue), + + CorsairChannelDeviceType.FanML => + new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "ML Fan"), updateQueue), + + CorsairChannelDeviceType.FanQL => + new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "QL Fan"), updateQueue), + + CorsairChannelDeviceType.EightLedSeriesFan => + new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "8-Led-Series Fan Fan"), updateQueue), + + CorsairChannelDeviceType.DAP => + new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "DAP Fan"), updateQueue), + + CorsairChannelDeviceType.Pump => + new CorsairCoolerRGBDevice(new CorsairCoolerRGBDeviceInfo(device, ledCount, offset, "Pump"), updateQueue), + + CorsairChannelDeviceType.WaterBlock => + new CorsairCoolerRGBDevice(new CorsairCoolerRGBDeviceInfo(device, ledCount, offset, "Water Block"), updateQueue), + + CorsairChannelDeviceType.Strip => CreateLedStripDevice(device, ledCount, offset, updateQueue), + + CorsairChannelDeviceType.DRAM => + new CorsairMemoryRGBDevice(new CorsairMemoryRGBDeviceInfo(device, ledCount, offset, "DRAM"), updateQueue), + + _ => throw new RGBDeviceException("Unknown Device-Type") + }; + } + + private static CorsairLedStripRGBDevice CreateLedStripDevice(_CorsairDeviceInfo device, int ledCount, int offset, + CorsairDeviceUpdateQueue updateQueue) + { + string modelName = "LED Strip"; + + // LS100 Led Strips are reported as one big strip if configured in monitor mode in iCUE, 138 LEDs for dual monitor, 84 for single + if ((device.model == "LS100 Starter Kit") && (ledCount == 138)) + modelName = "LS100 LED Strip (dual monitor)"; + else if ((device.model == "LS100 Starter Kit") && (ledCount == 84)) + modelName = "LS100 LED Strip (single monitor)"; + // Any other value means an "External LED Strip" in iCUE, these are reported per-strip, 15 for short strips, 27 for long + else if ((device.model == "LS100 Starter Kit") && (ledCount == 15)) + modelName = "LS100 LED Strip (short)"; + else if ((device.model == "LS100 Starter Kit") && (ledCount == 27)) + modelName = "LS100 LED Strip (long)"; + + CorsairLedStripRGBDevice ledStripDevice = new(new CorsairLedStripRGBDeviceInfo(device, ledCount, offset, modelName), updateQueue); + return ledStripDevice; + } + /// public override void Dispose() { diff --git a/RGB.NET.Devices.Corsair/Enum/CorsairEventId.cs b/RGB.NET.Devices.Corsair/Enum/CorsairEventId.cs new file mode 100644 index 00000000..c1b8988b --- /dev/null +++ b/RGB.NET.Devices.Corsair/Enum/CorsairEventId.cs @@ -0,0 +1,8 @@ +namespace RGB.NET.Devices.Corsair; + +internal enum CorsairEventId +{ + Invalid = 0, + DeviceConnectionStatusChangedEvent = 1, + KeyEvent = 2, +} diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs index 9fcbca62..3faa86ff 100644 --- a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs @@ -14,6 +14,11 @@ public abstract class CorsairRGBDevice : AbstractRGBDevice + /// + /// + public string DeviceId => DeviceInfo.DeviceId; + /// /// Gets the mapping of to used to update the LEDs of this device. /// @@ -29,7 +34,7 @@ public abstract class CorsairRGBDevice : AbstractRGBDeviceThe generic information provided by CUE for the device. /// The mapping to used to update the LEDs of this device. /// The queue used to update this device. - protected CorsairRGBDevice(TDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + protected CorsairRGBDevice(TDeviceInfo info, IUpdateQueue updateQueue) : base(info, updateQueue) { } @@ -37,6 +42,24 @@ protected CorsairRGBDevice(TDeviceInfo info, CorsairDeviceUpdateQueue updateQueu #region Methods + protected bool Equals(CorsairRGBDevice other) + { + return DeviceId == other.DeviceId; + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((CorsairRGBDevice)obj); + } + + public override int GetHashCode() + { + return DeviceId.GetHashCode(); + } + void ICorsairRGBDevice.Initialize() => InitializeLayout(); /// diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs index 6137b95a..3cdb6c0e 100644 --- a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs @@ -1,4 +1,7 @@ -using System.Text.RegularExpressions; +using System; +using System.Security.Cryptography; +using System.Text; +using System.Text.RegularExpressions; using RGB.NET.Core; using RGB.NET.Devices.Corsair.Native; @@ -33,7 +36,7 @@ public class CorsairRGBDeviceInfo : IRGBDeviceInfo /// Returns the unique ID provided by the Corsair-SDK. /// Returns string.Empty for Custom devices. /// - public string DeviceId { get; } + public string DeviceId { get; init; } /// public object? LayoutMetadata { get; set; } @@ -67,7 +70,7 @@ internal CorsairRGBDeviceInfo(RGBDeviceType deviceType, _CorsairDeviceInfo nativ this.LedCount = ledCount; this.LedOffset = ledOffset; - DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); + DeviceName = Manufacturer + " " + Model + " " + HashAndShorten(DeviceId); } /// @@ -86,7 +89,27 @@ internal CorsairRGBDeviceInfo(RGBDeviceType deviceType, _CorsairDeviceInfo nativ this.LedCount = ledCount; this.LedOffset = ledOffset; - DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); + DeviceName = Manufacturer + " " + Model + " " + HashAndShorten(DeviceId) + " " + ledOffset; + } + + #endregion + + #region Methods + + private static string HashAndShorten(string input) + { + using SHA256 sha256Hash = SHA256.Create(); + byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(input)); + // Take the first 4 bytes of the hash + byte[] shortenedBytes = new byte[4]; + Array.Copy(bytes, shortenedBytes, 4); + // Convert the bytes to a string + StringBuilder shortenedHash = new(); + foreach (byte b in shortenedBytes) + { + shortenedHash.Append(b.ToString("X2")); + } + return shortenedHash.ToString(); } #endregion diff --git a/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs b/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs index 5e49da25..9bfde69a 100644 --- a/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs @@ -7,5 +7,7 @@ namespace RGB.NET.Devices.Corsair; /// public interface ICorsairRGBDevice : IRGBDevice { + internal string DeviceId { get; } + internal void Initialize(); } \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Native/_CUESDK.cs b/RGB.NET.Devices.Corsair/Native/_CUESDK.cs index 00d9f922..ac7d90ce 100644 --- a/RGB.NET.Devices.Corsair/Native/_CUESDK.cs +++ b/RGB.NET.Devices.Corsair/Native/_CUESDK.cs @@ -12,6 +12,7 @@ namespace RGB.NET.Devices.Corsair.Native; internal delegate void CorsairSessionStateChangedHandler(nint context, _CorsairSessionStateChanged eventData); +internal delegate void CorsairEventHandler(nint context, _CorsairEvent corsairEvent); // ReSharper disable once InconsistentNaming internal static unsafe class _CUESDK @@ -47,23 +48,59 @@ internal static unsafe class _CUESDK #region Properties & Fields - internal static bool IsConnected => SesionState == CorsairSessionState.Connected; - internal static CorsairSessionState SesionState { get; private set; } + internal static bool IsConnected => SessionState == CorsairSessionState.Connected; + internal static CorsairSessionState SessionState { get; private set; } #endregion #region Events internal static event EventHandler? SessionStateChanged; + internal static event EventHandler<_CorsairDeviceConnectionStatusChangedEvent>? DeviceConnectionEvent; #endregion #region Methods - private static void CorsairSessionStateChangedCallback(nint context, _CorsairSessionStateChanged eventdata) + private static void CorsairSessionStateChangedCallback(nint context, _CorsairSessionStateChanged eventData) { - SesionState = eventdata.state; - SessionStateChanged?.Invoke(null, eventdata.state); + SessionState = eventData.state; + try + { + SessionStateChanged?.Invoke(null, eventData.state); + } + catch { /* dont let exception go to sdk */ } + + switch (eventData.state) + { + case CorsairSessionState.Connected: + _corsairSubscribeForEvents(CorsairEventCallback, 0); + break; + case CorsairSessionState.Closed: + _corsairUnsubscribeForEvents(); + break; + } + } + + private static void CorsairEventCallback(nint context, _CorsairEvent eventData) + { + if (eventData.id != CorsairEventId.DeviceConnectionStatusChangedEvent) + { + return; + } + + try + { + if (eventData.eventPointer == 0) + { + return; + } + + _CorsairDeviceConnectionStatusChangedEvent connectionStatusChangedEvent = + Marshal.PtrToStructure<_CorsairDeviceConnectionStatusChangedEvent>(eventData.eventPointer)!; + + DeviceConnectionEvent?.Invoke(null, connectionStatusChangedEvent); + }catch { /* dont let exception go to sdk */ } } #endregion @@ -97,7 +134,7 @@ private static void LoadCUESDK() _corsairGetSessionDetails = (delegate* unmanaged[Cdecl])LoadFunction("CorsairGetSessionDetails"); _corsairDisconnect = (delegate* unmanaged[Cdecl])LoadFunction("CorsairDisconnect"); _corsairGetDevices = (delegate* unmanaged[Cdecl]<_CorsairDeviceFilter, int, nint, out int, CorsairError>)LoadFunction("CorsairGetDevices"); - _corsairGetDeviceInfo = (delegate* unmanaged[Cdecl])LoadFunction("CorsairGetDeviceInfo"); + _corsairGetDeviceInfo = (delegate* unmanaged[Cdecl])LoadFunction("CorsairGetDeviceInfo"); _corsairGetLedPositions = (delegate* unmanaged[Cdecl])LoadFunction("CorsairGetLedPositions"); _corsairSetLedColors = (delegate* unmanaged[Cdecl])LoadFunction("CorsairSetLedColors"); _corsairSetLayerPriority = (delegate* unmanaged[Cdecl])LoadFunction("CorsairSetLayerPriority"); @@ -106,6 +143,8 @@ private static void LoadCUESDK() _corsairReleaseControl = (delegate* unmanaged[Cdecl])LoadFunction("CorsairReleaseControl"); _getDevicePropertyInfo = (delegate* unmanaged[Cdecl])LoadFunction("CorsairGetDevicePropertyInfo"); _readDeviceProperty = (delegate* unmanaged[Cdecl])LoadFunction("CorsairReadDeviceProperty"); + _corsairSubscribeForEvents = (delegate* unmanaged[Cdecl])LoadFunction("CorsairSubscribeForEvents"); + _corsairUnsubscribeForEvents = (delegate* unmanaged[Cdecl])LoadFunction("CorsairSubscribeForEvents"); } private static nint LoadFunction(string function) @@ -158,7 +197,7 @@ internal static void UnloadCUESDK() private static delegate* unmanaged[Cdecl] _corsairGetSessionDetails; private static delegate* unmanaged[Cdecl] _corsairDisconnect; private static delegate* unmanaged[Cdecl]<_CorsairDeviceFilter, int, nint, out int, CorsairError> _corsairGetDevices; - private static delegate* unmanaged[Cdecl] _corsairGetDeviceInfo; + private static delegate* unmanaged[Cdecl] _corsairGetDeviceInfo; private static delegate* unmanaged[Cdecl] _corsairGetLedPositions; private static delegate* unmanaged[Cdecl] _corsairSetLedColors; private static delegate* unmanaged[Cdecl] _corsairSetLayerPriority; @@ -167,6 +206,8 @@ internal static void UnloadCUESDK() private static delegate* unmanaged[Cdecl] _corsairReleaseControl; private static delegate* unmanaged[Cdecl] _getDevicePropertyInfo; private static delegate* unmanaged[Cdecl] _readDeviceProperty; + private static delegate* unmanaged[Cdecl] _corsairSubscribeForEvents; + private static delegate* unmanaged[Cdecl] _corsairUnsubscribeForEvents; #endregion @@ -220,10 +261,12 @@ internal static CorsairError CorsairGetDevices(_CorsairDeviceFilter filter, out } } - internal static CorsairError CorsairGetDeviceInfo(string deviceId, _CorsairDeviceInfo deviceInfo) + internal static CorsairError CorsairGetDeviceInfo(string deviceId, out _CorsairDeviceInfo deviceInfo) { if (!IsConnected) throw new RGBDeviceException("The Corsair-SDK is not connected."); - return _corsairGetDeviceInfo(deviceId, deviceInfo); + + deviceInfo = new _CorsairDeviceInfo(); + return _corsairGetDeviceInfo(deviceId, ref deviceInfo); } internal static CorsairError CorsairGetLedPositions(string deviceId, out _CorsairLedPosition[] ledPositions) diff --git a/RGB.NET.Devices.Corsair/Native/_CorsairDeviceConnectionStatusChangedEvent.cs b/RGB.NET.Devices.Corsair/Native/_CorsairDeviceConnectionStatusChangedEvent.cs new file mode 100644 index 00000000..bc71d914 --- /dev/null +++ b/RGB.NET.Devices.Corsair/Native/_CorsairDeviceConnectionStatusChangedEvent.cs @@ -0,0 +1,19 @@ +using System.Runtime.InteropServices; + +namespace RGB.NET.Devices.Corsair.Native; + +[StructLayout(LayoutKind.Sequential)] +public class _CorsairDeviceConnectionStatusChangedEvent +{ + /// + /// iCUE-SDK: null terminated Unicode string that contains unique device identifier + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = _CUESDK.CORSAIR_STRING_SIZE_M)] + internal string? deviceId; + + /// + /// iCUE-SDK: true if connected, false if disconnected + /// + [MarshalAs(UnmanagedType.U1)] + internal bool isConnected; +} diff --git a/RGB.NET.Devices.Corsair/Native/_CorsairDeviceInfo.cs b/RGB.NET.Devices.Corsair/Native/_CorsairDeviceInfo.cs index b4c8813d..2fc6e31d 100644 --- a/RGB.NET.Devices.Corsair/Native/_CorsairDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/Native/_CorsairDeviceInfo.cs @@ -12,7 +12,7 @@ namespace RGB.NET.Devices.Corsair.Native; /// iCUE-SDK: contains information about device /// [StructLayout(LayoutKind.Sequential)] -internal sealed class _CorsairDeviceInfo +internal struct _CorsairDeviceInfo { /// /// iCUE-SDK: enum describing device type diff --git a/RGB.NET.Devices.Corsair/Native/_CorsairEvent.cs b/RGB.NET.Devices.Corsair/Native/_CorsairEvent.cs new file mode 100644 index 00000000..6f5285ad --- /dev/null +++ b/RGB.NET.Devices.Corsair/Native/_CorsairEvent.cs @@ -0,0 +1,22 @@ +using System.Runtime.InteropServices; + +namespace RGB.NET.Devices.Corsair.Native; + +// ReSharper disable once InconsistentNaming +/// +/// iCUE-SDK: contains information about event id and event data +/// +[StructLayout(LayoutKind.Sequential)] +internal sealed class _CorsairEvent +{ + /// + /// iCUE-SDK: event identifier + /// + internal CorsairEventId id; + + /// + /// Points to if _CorsairEvent's id is CEI_DeviceConnectionStatusChangedEvent, + /// points to if _CorsairEvent's id is CEI_KeyEvent + /// + internal nint eventPointer; +} From f7bcc35e570902bfc61730a977afda17e23cafb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ayta=C3=A7=20Kayadelen?= Date: Tue, 20 Jun 2023 23:36:02 +0200 Subject: [PATCH 2/6] made device name generation consistent with openrgb --- RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs index 3cdb6c0e..d6a9db28 100644 --- a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs @@ -70,7 +70,7 @@ internal CorsairRGBDeviceInfo(RGBDeviceType deviceType, _CorsairDeviceInfo nativ this.LedCount = ledCount; this.LedOffset = ledOffset; - DeviceName = Manufacturer + " " + Model + " " + HashAndShorten(DeviceId); + DeviceName = Manufacturer + " " + Model + " #" + HashAndShorten(DeviceId); } /// @@ -89,7 +89,7 @@ internal CorsairRGBDeviceInfo(RGBDeviceType deviceType, _CorsairDeviceInfo nativ this.LedCount = ledCount; this.LedOffset = ledOffset; - DeviceName = Manufacturer + " " + Model + " " + HashAndShorten(DeviceId) + " " + ledOffset; + DeviceName = Manufacturer + " " + Model + " #" + HashAndShorten(DeviceId) + " " + ledOffset; } #endregion From e81ac3b98ead86e579017534624f74a6492ad62e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ayta=C3=A7=20Kayadelen?= Date: Thu, 22 Jun 2023 00:46:13 +0200 Subject: [PATCH 3/6] Fixes for load fail and removing dispose when duplicate device is added --- .../Devices/AbstractRGBDeviceProvider.cs | 9 +++++++++ .../Update/Devices/DeviceUpdateTrigger.cs | 8 ++++++-- .../CorsairDeviceProvider.cs | 19 +++++++++++++------ RGB.NET.Devices.Corsair/Native/_CUESDK.cs | 6 ++++-- 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs index ebcc6273..5a79d554 100644 --- a/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs +++ b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs @@ -89,6 +89,15 @@ public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwE Reset(); throw; } + catch (RGBDeviceException) + { + Reset(); + if (throwExceptions) + { + throw; + } + return false; + } catch (Exception ex) { Reset(); diff --git a/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs b/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs index a45ae6ca..2957fb85 100644 --- a/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs +++ b/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs @@ -141,11 +141,15 @@ public virtual async void Stop() UpdateTokenSource?.Cancel(); if (UpdateTask != null) - try { await UpdateTask.ConfigureAwait(false); } + try + { + await UpdateTask.ConfigureAwait(false); + UpdateTask?.Dispose(); + } catch (TaskCanceledException) { } catch (OperationCanceledException) { } + catch (InvalidOperationException) { } - UpdateTask?.Dispose(); UpdateTask = null; } diff --git a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs index f8c68b2f..1d953bec 100644 --- a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs +++ b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs @@ -91,6 +91,7 @@ public CorsairDeviceProvider() protected override void InitializeSDK() { + _CUESDK.SessionStateChanged -= CancelOnConnect; _CUESDK.Reload(); using ManualResetEventSlim waitEvent = new(false); @@ -112,7 +113,10 @@ void OnInitializeSessionStateChanged(object? sender, CorsairSessionState state) Throw(new RGBDeviceException($"Failed to initialized Corsair-SDK. (ErrorCode: {errorCode})")); if (!waitEvent.Wait(ConnectionTimeout)) + { + _CUESDK.SessionStateChanged += CancelOnConnect; //We can't cancel connection. All we can do is disconnect after connection Throw(new RGBDeviceException($"Failed to initialized Corsair-SDK. (Timeout - Current connection state: {_CUESDK.SessionState})")); + } _CUESDK.CorsairGetSessionDetails(out _CorsairSessionDetails? details); if (errorCode != CorsairError.Success) @@ -126,7 +130,14 @@ void OnInitializeSessionStateChanged(object? sender, CorsairSessionState state) _CUESDK.SessionStateChanged -= OnInitializeSessionStateChanged; } } - + + private void CancelOnConnect(object? sender, CorsairSessionState e) + { + if (e != CorsairSessionState.Connected) return; + _CUESDK.SessionStateChanged -= CancelOnConnect; + _CUESDK.CorsairDisconnect(); + } + private void OnDeviceConnectionEvent(object? sender, _CorsairDeviceConnectionStatusChangedEvent connectionStatusChangedEvent) { string? deviceId = connectionStatusChangedEvent.deviceId; @@ -139,11 +150,7 @@ private void OnDeviceConnectionEvent(object? sender, _CorsairDeviceConnectionSta foreach (ICorsairRGBDevice corsairRGBDevice in device) { corsairRGBDevice.Initialize(); - if (!AddDevice(corsairRGBDevice)) - { - deviceUpdateTrigger.Dispose(); - } - else + if (AddDevice(corsairRGBDevice)) { deviceUpdateTrigger.Start(); } diff --git a/RGB.NET.Devices.Corsair/Native/_CUESDK.cs b/RGB.NET.Devices.Corsair/Native/_CUESDK.cs index ac7d90ce..70a8b4d4 100644 --- a/RGB.NET.Devices.Corsair/Native/_CUESDK.cs +++ b/RGB.NET.Devices.Corsair/Native/_CUESDK.cs @@ -214,7 +214,10 @@ internal static void UnloadCUESDK() internal static CorsairError CorsairConnect() { if (_corsairConnectPtr == null) throw new RGBDeviceException("The Corsair-SDK is not initialized."); - if (IsConnected) throw new RGBDeviceException("The Corsair-SDK is already connected."); + if (SessionState is CorsairSessionState.Connecting or CorsairSessionState.Timeout) + { + return CorsairError.Success; + } return _corsairConnectPtr(CorsairSessionStateChangedCallback, 0); } @@ -238,7 +241,6 @@ internal static CorsairError CorsairGetSessionDetails(out _CorsairSessionDetails internal static CorsairError CorsairDisconnect() { - if (!IsConnected) throw new RGBDeviceException("The Corsair-SDK is not connected."); return _corsairDisconnect(); } From d53fc8818fc955d35f300b45ec07706d3489864c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ayta=C3=A7=20Kayadelen?= Date: Sun, 9 Jul 2023 14:34:01 +0200 Subject: [PATCH 4/6] change id generation based on object typed key --- RGB.NET.Core/Ids/IdGenerator.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RGB.NET.Core/Ids/IdGenerator.cs b/RGB.NET.Core/Ids/IdGenerator.cs index c6270e7c..2d8e200e 100644 --- a/RGB.NET.Core/Ids/IdGenerator.cs +++ b/RGB.NET.Core/Ids/IdGenerator.cs @@ -13,8 +13,8 @@ public static class IdGenerator // ReSharper disable InconsistentNaming private static readonly HashSet _registeredIds = new(); - private static readonly Dictionary> _idMappings = new(); - private static readonly Dictionary> _counter = new(); + private static readonly Dictionary> _idMappings = new(); + private static readonly Dictionary> _counter = new(); // ReSharper restore InconsistentNaming #endregion @@ -29,7 +29,7 @@ public static class IdGenerator [MethodImpl(MethodImplOptions.NoInlining)] public static string MakeUnique(string id) => MakeUnique(Assembly.GetCallingAssembly(), id); - internal static string MakeUnique(Assembly callingAssembly, string id) + public static string MakeUnique(object callingAssembly, string id) { if (!_idMappings.TryGetValue(callingAssembly, out Dictionary? idMapping)) { @@ -63,7 +63,7 @@ internal static string MakeUnique(Assembly callingAssembly, string id) [MethodImpl(MethodImplOptions.NoInlining)] public static void ResetCounter() => ResetCounter(Assembly.GetCallingAssembly()); - internal static void ResetCounter(Assembly callingAssembly) + public static void ResetCounter(object callingAssembly) { if (_counter.TryGetValue(callingAssembly, out Dictionary? counter)) counter.Clear(); From 9c5b25ecaf17060c40f23715d5f97c88b08de52b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ayta=C3=A7=20Kayadelen?= Date: Sun, 9 Jul 2023 14:34:15 +0200 Subject: [PATCH 5/6] Handle name generations for unpluggable devices --- .../CorsairDeviceProvider.cs | 2 ++ .../Generic/CorsairRGBDeviceInfo.cs | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs index 1d953bec..2291ab2f 100644 --- a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs +++ b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs @@ -349,6 +349,8 @@ public override void Dispose() try { _CUESDK.CorsairDisconnect(); } catch { /* at least we tried */ } try { _CUESDK.UnloadCUESDK(); } catch { /* at least we tried */ } + + IdGenerator.ResetCounter(typeof(CorsairDeviceProvider)); } #endregion diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs index d6a9db28..c7560bbb 100644 --- a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs @@ -70,7 +70,14 @@ internal CorsairRGBDeviceInfo(RGBDeviceType deviceType, _CorsairDeviceInfo nativ this.LedCount = ledCount; this.LedOffset = ledOffset; - DeviceName = Manufacturer + " " + Model + " #" + HashAndShorten(DeviceId); + if (nativeInfo.id == null) // this device is 99% unpluggable + { + DeviceName = IdGenerator.MakeUnique(typeof(CorsairDeviceProvider), Manufacturer + " " + Model); + } + else + { + DeviceName = Manufacturer + " " + Model + " #" + HashAndShorten(DeviceId); + } } /// @@ -89,7 +96,14 @@ internal CorsairRGBDeviceInfo(RGBDeviceType deviceType, _CorsairDeviceInfo nativ this.LedCount = ledCount; this.LedOffset = ledOffset; - DeviceName = Manufacturer + " " + Model + " #" + HashAndShorten(DeviceId) + " " + ledOffset; + if (nativeInfo.id == null) + { + DeviceName = IdGenerator.MakeUnique(typeof(CorsairDeviceProvider),Manufacturer + " " + Model) + " " + ledOffset;; + } + else + { + DeviceName = Manufacturer + " " + Model + " #" + HashAndShorten(DeviceId) + " " + ledOffset; + } } #endregion From 4ff11a017caf091dc18d280d22f3c3f8edaae5ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ayta=C3=A7=20Kayadelen?= Date: Mon, 1 Jan 2024 21:44:24 +0100 Subject: [PATCH 6/6] reformat adjustments --- RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs index 23a6479b..e4d13adf 100644 --- a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs +++ b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs @@ -284,9 +284,10 @@ private static ICorsairRGBDevice CreateSingleChannelDevice(_CorsairDeviceInfo de CorsairDeviceType.Cooler => new CorsairCoolerRGBDevice(new CorsairCoolerRGBDeviceInfo(device, deviceLedCount, 0), updateQueue), + CorsairDeviceType.GameController => new CorsairGameControllerRGBDevice(new CorsairGameControllerRGBDeviceInfo(device, deviceLedCount, 0), updateQueue), - + CorsairDeviceType.FanLedController or CorsairDeviceType.LedController or CorsairDeviceType.Unknown => @@ -315,10 +316,10 @@ private static ICorsairRGBDevice CreateCorsairDeviceChannel(_CorsairDeviceInfo d CorsairChannelDeviceType.FanQL => new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "QL Fan"), updateQueue), - + CorsairChannelDeviceType.FanQX => new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "QX Fan"), updateQueue), - + CorsairChannelDeviceType.EightLedSeriesFan => new CorsairFanRGBDevice(new CorsairFanRGBDeviceInfo(device, ledCount, offset, "8-Led-Series Fan Fan"), updateQueue), @@ -340,8 +341,7 @@ private static ICorsairRGBDevice CreateCorsairDeviceChannel(_CorsairDeviceInfo d }; } - private static CorsairLedStripRGBDevice CreateLedStripDevice(_CorsairDeviceInfo device, int ledCount, int offset, - CorsairDeviceUpdateQueue updateQueue) + private static CorsairLedStripRGBDevice CreateLedStripDevice(_CorsairDeviceInfo device, int ledCount, int offset, CorsairDeviceUpdateQueue updateQueue) { string modelName = "LED Strip";