using System; using System.Collections.Generic; using System.Text; using LibUsbDotNet; using LibUsbDotNet.Main; using Salamax.Logging; namespace Salamax { public class Xbox360Controller : USBDevice { private const int _VENDOR_ID = 0x15E4; private const int _PRODUCT_ID = 0x3F00; private int _vendorId = _VENDOR_ID; private int _productId = _PRODUCT_ID; private IUsbDevice _device = null; private UsbEndpointWriter _writer = null; public Xbox360Controller() { Find(); } public int VendorId { get { return _vendorId; } } public int ProductId { get { return _productId; } } public override bool IsConnected { get { return (_device != null && _device.IsOpen); } } public override void Find() { Find(_vendorId, _productId); } private byte[] _written = new byte[] { 0x01, 0x03, 0x00 }; public void Find(int vendorId, int productId) { bool wasValid = (_device != null && _device.IsOpen); _vendorId = vendorId; _productId = productId; //Find the Xbox 360 controller bool found = _FindController(); if (found) { if (!wasValid) { Logger.WriteLine("Xbox 360 controller found, initializing...", Logger.Type.Warning); //int transferred; _writer = _device.OpenEndpointWriter(WriteEndpointID.Ep02); //_writer.Write(_written, 5000, 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 (_writer != null) { _writer.Abort(); _writer.Dispose(); _writer = null; } if (_device != null && _device.IsOpen) { _device.Close(); _device = null; } } public bool DoControlTransfer(ref UsbSetupPacket setup, ref byte[] buffer, int length, out int transferred) { return _device.ControlTransfer(ref setup, buffer, length, out transferred); } 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; _device = LibUsbDotNet.UsbDevice.OpenUsbDevice(new UsbDeviceFinder(_vendorId, _productId)) as IUsbDevice; if (_device != null) ret = true; return ret; } } }