using System; using System.Collections.Generic; using System.Text; using LibUsbDotNet; using LibUsbDotNet.Main; namespace Salamax { public class Xbox360Controller : USBDevice { private UsbDevice _device = null; public override bool IsConnected { get { return (_device != null && _device.IsOpen); } } public override void Find() { bool wasValid = (_device != null && _device.IsOpen); //Find the Xbox 360 controller bool found = _FindController(); if (found) { if (!wasValid) { Logger.WriteLine("Xbox 360 controller found, initializing...", Logger.Type.Warning); /* var device = _device as IUsbDevice; device.ResetDevice(); System.Threading.Thread.Sleep(3000); _FindController(); * */ var writer = _device.OpenEndpointWriter(WriteEndpointID.Ep02, EndpointType.Interrupt); int transferred; writer.Write(new byte[] { 0x01, 0x03, 0x00 }, 10000, out transferred); Logger.WriteLine("Xbox 360 controller initialized.", Logger.Type.Information); } } else { if (_device != null) { _device = null; Logger.WriteLine("Xbox 360 controller disconnected.", Logger.Type.Warning); } } } public override void Disconnect() { if (_device != null && _device.IsOpen) { _device.Close(); } } public byte[] RequestStaticData() { var ret = new byte[0x1D]; int transferred; Logger.WriteLine("Setting Xbox 360 controller configuration 1.", Logger.Type.Information); var setup = new UsbSetupPacket(0x00, 0x09, 0x0001, 0x00000, 0x0000); var success = _device.ControlTransfer(ref setup, IntPtr.Zero, 0x0000, out transferred); Logger.WriteLine("Requesting Xbox 360 controller security string descriptor...", Logger.Type.Information); setup = new UsbSetupPacket(0x80, 0x06, 0x0304, 0x0409, 0x00B2); var buffer = new byte[0x00B2]; success = _device.ControlTransfer(ref setup, buffer, 0x00B2, out transferred); setup = new UsbSetupPacket(0xC1, 0x81, 0x5B17, 0x0103, 0x001D); Logger.WriteLine("Requesting static data from controller...", Logger.Type.Information); if (_device.ControlTransfer(ref setup, ret, 0x001D, out transferred)) Logger.WriteLine("Static controller data received successfully.", Logger.Type.Information); return ret; } public byte[] DoChallenge1(byte[] data) { int transferred; var ret = new byte[0x2E]; Logger.WriteLine("Sending first challenge to Xbox 360 controller...", Logger.Type.Information); var setup = new UsbSetupPacket(0x41, 0x82, 0x0003, 0x0103, 0x0022); if (_device.ControlTransfer(ref setup, data, 0x0022, out transferred)) { //Wait till the controller is done with our response bool complete = false; do { setup = new UsbSetupPacket(0xC1, 0x86, 0x0000, 0x0103, 0x0002); var response = new byte[0x0002]; if (_device.ControlTransfer(ref setup, response, 0x0002, out transferred) && transferred == 2) { Logger.WriteLine("Checking status of first response from Xbox 360 controller: " + response[0].ToString("X2"), Logger.Type.Information); if (response[0] > 1) complete = true; } System.Threading.Thread.Sleep(100); } while (!complete); Logger.WriteLine("First response is ready from Xbox 360 controller.", Logger.Type.Information); //Get the response setup = new UsbSetupPacket(0xC1, 0x83, 0x5C28, 0x0103, 0x002E); Logger.WriteLine("Requesting first response from Xbox 360 controller...", Logger.Type.Information); if (_device.ControlTransfer(ref setup, ret, 0x002E, out transferred)) { Logger.WriteLine("Sending next step to Xbox 360 controller...", Logger.Type.Information); setup = new UsbSetupPacket(0x41, 0x84, 0x0003, 0x0103, 0x0000); _device.ControlTransfer(ref setup, IntPtr.Zero, 0, out transferred); } else Logger.WriteLine("First response request from Xbox 360 controller failed.", Logger.Type.Error); } else Logger.WriteLine("Sending first challenge to Xbox 360 controller failed.", Logger.Type.Error); return ret; } public byte[] DoChallenge2(byte[] data) { int transferred; var ret = new byte[0x16]; Logger.WriteLine("Sending second challenge to Xbox 360 controller...", Logger.Type.Information); var setup = new UsbSetupPacket(0x41, 0x87, 0x0003, 0x0103, 0x0016); var buffer = new byte[0x100]; for (int i = 0; i < data.Length; i++) buffer[i] = data[i]; if (_device.ControlTransfer(ref setup, buffer, 0x0016, out transferred)) { //Wait till the controller is done with our response bool complete = false; do { setup = new UsbSetupPacket(0xC1, 0x86, 0x0000, 0x0103, 0x0002); var response = new byte[0x0002]; if (_device.ControlTransfer(ref setup, response, 0x0002, out transferred) && transferred == 2) { Logger.WriteLine("Checking status of second response from Xbox 360 controller: " + response[0].ToString("X2"), Logger.Type.Information); if (response[0] > 1) complete = true; } System.Threading.Thread.Sleep(100); } while (!complete); Logger.WriteLine("Second response is ready from Xbox 360 controller.", Logger.Type.Information); //Get the response setup = new UsbSetupPacket(0xC1, 0x83, 0x5C10, 0x0103, 0x0016); Logger.WriteLine("Requesting second response from Xbox 360 controller...", Logger.Type.Information); if (_device.ControlTransfer(ref setup, ret, 0x0016, out transferred)) { Logger.WriteLine("Sending next step to Xbox 360 controller...", Logger.Type.Information); setup = new UsbSetupPacket(0x41, 0x84, 0x0003, 0x0103, 0x0000); _device.ControlTransfer(ref setup, IntPtr.Zero, 0, out transferred); } else Logger.WriteLine("Second response request from Xbox 360 controller failed.", Logger.Type.Error); } else Logger.WriteLine("Sending second challenge to Xbox 360 controller failed.", Logger.Type.Error); return ret; } private bool _FindController() { bool ret = false; foreach (object reg in LibUsbDotNet.LibUsb.LibUsbRegistry.DeviceList) { if (reg.GetType() == typeof(LibUsbDotNet.LibUsb.LibUsbRegistry)) { var usb = reg as LibUsbDotNet.LibUsb.LibUsbRegistry; if (usb.Vid == 0x1BAD && usb.Pid == 0xF900) { _device = usb.Device; ret = true; break; } } } return ret; } } }