Skip to content

Commit baf1a3c

Browse files
committed
Apply Qodo /improve pass 2: case-insensitive device-path matching
Windows HID device paths are case-insensitive and casing can vary across enumerations; match paths with OrdinalIgnoreCase in both ConnectByPathAsync and the bootloader wait (consistent with the serial-filter comparison). Real device paths never differ only by case, so this cannot mis-target. Declined the redundant path re-validation suggestion (importance 2): the enumerated device is already matched by targetDevicePath in WaitForBootloaderDeviceAsync, so re-checking before connect adds nothing. Tests: +1 (case-insensitive match). Claude-Session: https://claude.ai/code/session_01V5TeJuikExLKXzxvYcQNxB
1 parent 3683475 commit baf1a3c

3 files changed

Lines changed: 19 additions & 2 deletions

File tree

src/Daqifi.Core.Tests/Communication/Transport/HidLibraryTransportTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,20 @@ public async Task ConnectByPathAsync_WithMatchingPath_OpensThatExactDevice()
124124
Assert.Equal(1, deviceB.OpenCount);
125125
}
126126

127+
[Fact]
128+
public async Task ConnectByPathAsync_MatchesPathCaseInsensitively()
129+
{
130+
// Windows HID device paths are case-insensitive; casing can vary across enumerations.
131+
var device = new FakeHidTransportDevice(0x04D8, 0x003C, "PATH-A", string.Empty);
132+
var platform = new FakeHidPlatform([device]);
133+
using var transport = new HidLibraryTransport(platform);
134+
135+
await transport.ConnectByPathAsync("path-a");
136+
137+
Assert.True(transport.IsConnected);
138+
Assert.Equal(1, device.OpenCount);
139+
}
140+
127141
[Fact]
128142
public async Task ConnectByPathAsync_WhenNoDeviceMatchesPath_ThrowsIOException()
129143
{

src/Daqifi.Core/Communication/Transport/HidLibraryTransport.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,11 @@ public async Task ConnectByPathAsync(string devicePath, CancellationToken cancel
123123
throw new ArgumentException("Device path cannot be null or empty.", nameof(devicePath));
124124
}
125125

126+
// Windows HID device paths are case-insensitive and their casing can vary across enumerations,
127+
// so match case-insensitively (real device paths never differ only by case, so this can't
128+
// mis-target). Mirrors the OrdinalIgnoreCase used for the serial filter in ConnectAsync.
126129
await ConnectMatchingDeviceAsync(
127-
candidate => string.Equals(candidate.DevicePath, devicePath, StringComparison.Ordinal),
130+
candidate => string.Equals(candidate.DevicePath, devicePath, StringComparison.OrdinalIgnoreCase),
128131
$"Path={devicePath}",
129132
cancellationToken).ConfigureAwait(false);
130133
}

src/Daqifi.Core/Firmware/FirmwareUpdateService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,7 @@ private async Task<HidDeviceInfo> WaitForBootloaderDeviceAsync(
11131113
var match = targetDevicePath == null
11141114
? devices.FirstOrDefault()
11151115
: devices.FirstOrDefault(d =>
1116-
string.Equals(d.DevicePath, targetDevicePath, StringComparison.Ordinal));
1116+
string.Equals(d.DevicePath, targetDevicePath, StringComparison.OrdinalIgnoreCase));
11171117
if (match != null)
11181118
{
11191119
return match;

0 commit comments

Comments
 (0)