If reading of hardware serial# (MAC) fails then readSerial function generates a runtime MAC adderss using devicePath value. This solves cases where UDPServer and Cemulator doesn't work with blank serials (and linkToProfile and 360SteeringWheel calibration linking to a certain gamepad).

This commit is contained in:
mika-n 2019-11-02 21:01:54 +02:00
parent e993d7eec7
commit 11008be55e

View File

@ -488,10 +488,6 @@ namespace DS4Windows
if (readFeatureData(buffer)) if (readFeatureData(buffer))
serial = String.Format("{0:X02}:{1:X02}:{2:X02}:{3:X02}:{4:X02}:{5:X02}", serial = String.Format("{0:X02}:{1:X02}:{2:X02}:{3:X02}:{4:X02}:{5:X02}",
buffer[6], buffer[5], buffer[4], buffer[3], buffer[2], buffer[1]); buffer[6], buffer[5], buffer[4], buffer[3], buffer[2], buffer[1]);
else
serial = BLANK_SERIAL;
return serial;
} }
else else
{ {
@ -507,11 +503,55 @@ namespace DS4Windows
MACAddr = $"{MACAddr[0]}{MACAddr[1]}:{MACAddr[2]}{MACAddr[3]}:{MACAddr[4]}{MACAddr[5]}:{MACAddr[6]}{MACAddr[7]}:{MACAddr[8]}{MACAddr[9]}:{MACAddr[10]}{MACAddr[11]}"; MACAddr = $"{MACAddr[0]}{MACAddr[1]}:{MACAddr[2]}{MACAddr[3]}:{MACAddr[4]}{MACAddr[5]}:{MACAddr[6]}{MACAddr[7]}:{MACAddr[8]}{MACAddr[9]}:{MACAddr[10]}{MACAddr[11]}";
serial = MACAddr; serial = MACAddr;
} }
else
serial = BLANK_SERIAL;
return serial;
} }
// If serial# reading failed then generate a dummy MAC address based on HID device path (WinOS generated runtime unique value based on connected usb port and hub or BT channel).
// The device path remains the same as long the gamepad is always connected to the same usb/BT port, but may be different in other usb ports. Therefore this value is unique
// as long the same device is always connected to the same usb port.
if (serial == null)
{
string MACAddr = string.Empty;
AppLogger.LogToGui($"WARNING: Failed to read serial# from a gamepad ({this._deviceAttributes.VendorHexId}/{this._deviceAttributes.ProductHexId}). Generating MAC address from a device path. From now on you should connect this gamepad always into the same USB port or BT pairing host to keep the same device path.", true);
try
{
// Substring: \\?\hid#vid_054c&pid_09cc&mi_03#7&1f882A25&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030} -> \\?\hid#vid_054c&pid_09cc&mi_03#7&1f882A25&0&0001#
int endPos = this.DevicePath.LastIndexOf('{');
if (endPos < 0)
endPos = this.DevicePath.Length;
// String array: \\?\hid#vid_054c&pid_09cc&mi_03#7&1f882A25&0&0001# -> [0]=\\?\hidvid_054c, [1]=pid_09cc, [2]=mi_037, [3]=1f882A25, [4]=0, [5]=0001
string[] devPathItems = this.DevicePath.Substring(0, endPos).Replace("#", "").Replace("-", "").Replace("{", "").Replace("}", "").Split('&');
if (devPathItems.Length >= 3)
MACAddr = devPathItems[devPathItems.Length - 3].ToUpper() // 1f882A25
+ devPathItems[devPathItems.Length - 2].ToUpper() // 0
+ devPathItems[devPathItems.Length - 1].TrimStart('0').ToUpper(); // 0001 -> 1
else if (devPathItems.Length >= 1)
// Device and usb hub and port identifiers missing in devicePath string. Fallback to use vendor and product ID values and
// take a number from the last part of the devicePath. Hopefully the last part is a usb port number as it usually should be.
MACAddr = this._deviceAttributes.VendorId.ToString("X4")
+ this._deviceAttributes.ProductId.ToString("X4")
+ devPathItems[devPathItems.Length - 1].TrimStart('0').ToUpper();
if (!string.IsNullOrEmpty(MACAddr))
{
MACAddr = MACAddr.PadRight(12, '0');
serial = $"{MACAddr[0]}{MACAddr[1]}:{MACAddr[2]}{MACAddr[3]}:{MACAddr[4]}{MACAddr[5]}:{MACAddr[6]}{MACAddr[7]}:{MACAddr[8]}{MACAddr[9]}:{MACAddr[10]}{MACAddr[11]}";
}
else
// Hmm... Shold never come here. Strange format in devicePath because all identifier items of devicePath string are missing.
serial = BLANK_SERIAL;
}
catch (Exception e)
{
AppLogger.LogToGui($"ERROR: Failed to generate runtime MAC address from device path {this.DevicePath}. {e.Message}", true);
serial = BLANK_SERIAL;
}
}
return serial;
} }
} }
} }