From 5a0fb09291ab6d2b3f14efa42cd544201e86f13f Mon Sep 17 00:00:00 2001 From: Travis Nickles Date: Thu, 25 May 2017 02:51:28 -0700 Subject: [PATCH] Update serial for Sony dongle connection upon sync event Related to issue #44. --- DS4Windows/DS4Control/ControlService.cs | 22 ++++++++++ DS4Windows/DS4Control/ScpUtil.cs | 32 ++++++++++++++ DS4Windows/DS4Forms/DS4Form.cs | 21 +++++++++ DS4Windows/DS4Library/DS4Device.cs | 57 +++++++++++++++++++++++++ DS4Windows/DS4Library/DS4Devices.cs | 30 +++++++++++-- DS4Windows/HidLibrary/HidDevice.cs | 5 +++ 6 files changed, 163 insertions(+), 4 deletions(-) diff --git a/DS4Windows/DS4Control/ControlService.cs b/DS4Windows/DS4Control/ControlService.cs index d132e95..d3a60fc 100644 --- a/DS4Windows/DS4Control/ControlService.cs +++ b/DS4Windows/DS4Control/ControlService.cs @@ -131,6 +131,8 @@ namespace DS4Windows DS4Controllers[i] = device; device.Removal += this.On_DS4Removal; device.Removal += DS4Devices.On_Removal; + device.SyncChange += DS4Devices.UpdateSerial; + device.SerialChange += this.On_SerialChange; touchPad[i] = new Mouse(i, device); device.LightBarColor = getMainColor(i); @@ -322,6 +324,8 @@ namespace DS4Windows DS4Controllers[Index] = device; device.Removal += this.On_DS4Removal; device.Removal += DS4Devices.On_Removal; + device.SyncChange += DS4Devices.UpdateSerial; + device.SerialChange += this.On_SerialChange; touchPad[Index] = new Mouse(Index, device); device.LightBarColor = getMainColor(Index); device.Report += this.On_Report; @@ -544,6 +548,23 @@ namespace DS4Windows return Properties.Resources.NoneText; } + protected void On_SerialChange(object sender, EventArgs e) + { + DS4Device device = (DS4Device)sender; + int ind = -1; + for (int i = 0, arlength = DS4_CONTROLLER_COUNT; ind == -1 && i < arlength; i++) + { + DS4Device tempDev = DS4Controllers[i]; + if (tempDev != null && device == tempDev) + ind = i; + } + + if (ind >= 0) + { + OnDeviceSerialChange(this, ind, device.getMacAddress()); + } + } + //Called when DS4 is disconnected or timed out protected virtual void On_DS4Removal(object sender, EventArgs e) { @@ -595,6 +616,7 @@ namespace DS4Windows Log.LogToTray(removed); System.Threading.Thread.Sleep(XINPUT_UNPLUG_SETTLE_TIME); device.IsRemoved = true; + device.Synced = false; DS4Controllers[ind] = null; touchPad[ind] = null; lag[ind] = false; diff --git a/DS4Windows/DS4Control/ScpUtil.cs b/DS4Windows/DS4Control/ScpUtil.cs index ab942ac..c51576f 100644 --- a/DS4Windows/DS4Control/ScpUtil.cs +++ b/DS4Windows/DS4Control/ScpUtil.cs @@ -202,6 +202,28 @@ namespace DS4Windows } } + public class SerialChangeArgs : EventArgs + { + private int index; + private string serial; + + public SerialChangeArgs(int index, string serial) + { + this.index = index; + this.serial = serial; + } + + public int getIndex() + { + return index; + } + + public string getSerial() + { + return serial; + } + } + public class MultiValueDict : Dictionary> { public void Add(Key key, Value val) @@ -323,6 +345,16 @@ namespace DS4Windows } } + public static event EventHandler DeviceSerialChange; + public static void OnDeviceSerialChange(object sender, int index, string serial) + { + if (DeviceSerialChange != null) + { + SerialChangeArgs args = new SerialChangeArgs(index, serial); + DeviceSerialChange(sender, args); + } + } + // general values public static bool UseExclusiveMode { diff --git a/DS4Windows/DS4Forms/DS4Form.cs b/DS4Windows/DS4Forms/DS4Form.cs index c2ca70a..aabd9f5 100644 --- a/DS4Windows/DS4Forms/DS4Form.cs +++ b/DS4Windows/DS4Forms/DS4Form.cs @@ -26,6 +26,7 @@ namespace DS4Windows delegate void BatteryStatusDelegate(object sender, BatteryReportArgs args); delegate void ControllerRemovedDelegate(object sender, ControllerRemovedArgs args); delegate void DeviceStatusChangedDelegate(object sender, DeviceStatusChangeEventArgs args); + delegate void DeviceSerialChangedDelegate(object sender, SerialChangeArgs args); protected Label[] Pads, Batteries; protected ComboBox[] cbs; protected Button[] ebns; @@ -332,6 +333,8 @@ namespace DS4Windows Global.BatteryStatusChange += BatteryStatusUpdate; Global.ControllerRemoved += ControllerRemovedChange; Global.DeviceStatusChange += DeviceStatusChanged; + Global.DeviceSerialChange += DeviceSerialChanged; + Enable_Controls(0, false); Enable_Controls(1, false); Enable_Controls(2, false); @@ -1071,6 +1074,24 @@ namespace DS4Windows } } + protected void DeviceSerialChanged(object sender, SerialChangeArgs args) + { + if (InvokeRequired) + { + DeviceSerialChangedDelegate d = new DeviceSerialChangedDelegate(DeviceSerialChanged); + this.BeginInvoke(d, new object[] { sender, args }); + } + else + { + int devIndex = args.getIndex(); + string serial = args.getSerial(); + if (devIndex >= 0 && devIndex < ControlService.DS4_CONTROLLER_COUNT) + { + Pads[devIndex].Text = serial; + } + } + } + protected void DeviceStatusChanged(object sender, DeviceStatusChangeEventArgs args) { if (this.InvokeRequired) diff --git a/DS4Windows/DS4Library/DS4Device.cs b/DS4Windows/DS4Library/DS4Device.cs index 2883b59..81f5b6a 100644 --- a/DS4Windows/DS4Library/DS4Device.cs +++ b/DS4Windows/DS4Library/DS4Device.cs @@ -124,6 +124,7 @@ namespace DS4Windows // and when a USB cable is connected private const int BATTERY_MAX = 8; private const int BATTERY_MAX_USB = 11; + public const string blankSerial = "00:00:00:00:00:00"; private HidDevice hDevice; private string Mac; private DS4State cState = new DS4State(); @@ -158,8 +159,11 @@ namespace DS4Windows private bool exitOutputThread = false; private bool exitInputThread = false; private object exitLocker = new object(); + public event EventHandler Report = null; public event EventHandler Removal = null; + public event EventHandler SyncChange = null; + public event EventHandler SerialChange = null; public HidDevice HidDevice => hDevice; public bool IsExclusive => HidDevice.IsExclusive; @@ -397,12 +401,14 @@ namespace DS4Windows if (conType == ConnectionType.USB) { warnInterval = WARN_INTERVAL_USB; + synced = true; } else { warnInterval = WARN_INTERVAL_BT; audio = new DS4Audio(); micAudio = new DS4Audio(DS4Library.CoreAudio.DataFlow.Render); + synced = isValidSerial(); } } else @@ -412,6 +418,7 @@ namespace DS4Windows outputReport = new byte[BT_OUTPUT_REPORT_LENGTH]; outputReportBuffer = new byte[BT_OUTPUT_REPORT_LENGTH]; warnInterval = WARN_INTERVAL_BT; + synced = isValidSerial(); } touchpad = new DS4Touchpad(); @@ -570,6 +577,25 @@ namespace DS4Windows } private byte priorInputReport30 = 0xff; + + private bool synced = false; + public bool Synced + { + get { return synced; } + set + { + if (synced != value) + { + synced = value; + } + } + } + + public bool isSynced() + { + return synced; + } + public double Latency = 0; public string error; public bool firstReport = false; @@ -772,6 +798,16 @@ namespace DS4Windows Console.WriteLine(); } */ + if (conType == ConnectionType.SONYWA) + { + bool noneSynced = inputReport[31] == 0; + if (noneSynced != synced) + { + SyncChange?.Invoke(this, EventArgs.Empty); + synced = noneSynced; + } + } + bool ds4Idle = cState.FrameCounter == pState.FrameCounter; if (!ds4Idle) { @@ -1180,5 +1216,26 @@ namespace DS4Windows eventQueue.Enqueue(act); } } + + public void updateSerial() + { + hDevice.resetSerial(); + string tempMac = hDevice.readSerial(); + if (tempMac != Mac) + { + Mac = tempMac; + SerialChange?.Invoke(this, EventArgs.Empty); + } + } + + public bool isValidSerial() + { + return !Mac.Equals(blankSerial); + } + + public static bool isValidSerial(string test) + { + return !test.Equals(blankSerial); + } } } diff --git a/DS4Windows/DS4Library/DS4Devices.cs b/DS4Windows/DS4Library/DS4Devices.cs index 33015da..daba4e3 100644 --- a/DS4Windows/DS4Library/DS4Devices.cs +++ b/DS4Windows/DS4Library/DS4Devices.cs @@ -95,7 +95,7 @@ namespace DS4Windows if (hDevice.IsOpen) { string serial = hDevice.readSerial(); - bool validSerial = !serial.Equals("00:00:00:00:00:00"); + bool validSerial = !serial.Equals(DS4Device.blankSerial); if (Devices.ContainsKey(serial)) continue; // happens when the BT endpoint already is open and the USB is plugged into the same host else @@ -162,9 +162,31 @@ namespace DS4Windows lock (Devices) { DS4Device device = (DS4Device)sender; - device.HidDevice.CloseDevice(); - Devices.Remove(device.MacAddress); - DevicePaths.Remove(device.HidDevice.DevicePath); + if (device != null) + { + device.HidDevice.CloseDevice(); + Devices.Remove(device.MacAddress); + DevicePaths.Remove(device.HidDevice.DevicePath); + } + } + } + + public static void UpdateSerial(object sender, EventArgs e) + { + lock (Devices) + { + DS4Device device = (DS4Device)sender; + if (device != null) + { + string serial = device.getMacAddress(); + if (Devices.ContainsKey(serial)) + { + Devices.Remove(serial); + device.updateSerial(); + serial = device.getMacAddress(); + Devices.Add(serial, device); + } + } } } diff --git a/DS4Windows/HidLibrary/HidDevice.cs b/DS4Windows/HidLibrary/HidDevice.cs index d98e19d..4f71cf1 100644 --- a/DS4Windows/HidLibrary/HidDevice.cs +++ b/DS4Windows/HidLibrary/HidDevice.cs @@ -471,6 +471,11 @@ namespace DS4Windows return NativeMethods.HidD_GetFeature(safeReadHandle.DangerousGetHandle(), inputBuffer, inputBuffer.Length); } + public void resetSerial() + { + serial = null; + } + public string readSerial() { if (serial != null)