public static byte[] ExecuteControlInTransfer(this IUsbHost usbHost, UsbSetupPacket setupPacket, int deviceAddress, int endpointNumber = 0) { var dataBuffer = new byte[setupPacket.wLength]; var result = usbHost.ExecuteControlTransfer(setupPacket, dataBuffer, 0, deviceAddress, endpointNumber); if (result.IsError) { throw new UsbTransferException(result.TransactionResult); } return(dataBuffer.Take(result.TransferredDataCount).ToArray()); }
public UsbTransferResult ExecuteControlTransfer(UsbSetupPacket setupPacket, byte[] dataBuffer, int dataBufferIndex, int deviceAddress, int endpointPacketSize, int endpointNumber = 0) { var requestedDataLength = (int)setupPacket.wLength; var remainingDataLength = requestedDataLength; UsbPacketResult result; SetTargetDeviceAddress(deviceAddress); //Setup WriteUsbData(setupPacket.ToByteArray()); IssueToken(endpointNumber, PID_SETUP, 0, 0); if ((result = WaitAndGetResult()) != UsbPacketResult.Ok) { return(new UsbTransferResult(result)); } //Data var dataTransferResult = setupPacket.DataDirection == UsbDataDirection.IN ? ExecuteDataInTransfer(dataBuffer, dataBufferIndex, requestedDataLength, deviceAddress, 0, endpointPacketSize, 1) : ExecuteDataOutTransfer(dataBuffer, dataBufferIndex, requestedDataLength, deviceAddress, 0, endpointPacketSize, 1); if (dataTransferResult.IsError) { return(dataTransferResult); } //Status if (setupPacket.DataDirection == UsbDataDirection.OUT || requestedDataLength == 0) { result = RepeatWhileNak(() => { IssueToken(endpointNumber, PID_IN, 1, 0); ReadUsbData(null); }); } else { result = RepeatWhileNak(() => { WriteUsbData(noData); IssueToken(endpointNumber, PID_OUT, 0, 1); }); } if (result != UsbPacketResult.Ok) { return(new UsbTransferResult(result)); } return(dataTransferResult); }
public static UsbSetupPacket FromWords(short[] packetWords) { if (packetWords.Length != 4) { throw new ArgumentException($"Length of {nameof(packetWords)} must be 4"); } var p = new UsbSetupPacket { bmRequestType = (byte)(packetWords[0] & 0x0F), bRequest = (byte)(packetWords[0] >> 8), wValue = packetWords[1], wIndex = packetWords[2], wLength = packetWords[3] }; return(p); }
public static UsbSetupPacket FromBytes(byte[] packetBytes) { if (packetBytes.Length != 8) { throw new ArgumentException($"Length of {nameof(packetBytes)} must be 8"); } var p = new UsbSetupPacket { bmRequestType = packetBytes[0], bRequest = packetBytes[1], wValueL = packetBytes[2], wValueH = packetBytes[3], wIndexL = packetBytes[4], wIndexH = packetBytes[5], wLengthL = packetBytes[6], wLengthH = packetBytes[7] }; return(p); }
public void ClearEndpointHalt(byte endpointNumber) { UsbTransferResult result; if (host.HostHardware is IUsbHardwareShortcuts) { result = ((IUsbHardwareShortcuts)host.HostHardware).ClearEndpointHalt(deviceAddress, endpointNumber); if (result.TransactionResult != UsbPacketResult.NotImplemented) { return; } } var setupPacket = new UsbSetupPacket(UsbStandardRequest.SET_FEATURE, 2); setupPacket.wIndexL = endpointNumber; result = host.ExecuteControlTransfer(setupPacket, null, 0, deviceAddress); setupPacket = new UsbSetupPacket(UsbStandardRequest.CLEAR_FEATURE, 2); setupPacket.wIndexL = endpointNumber; result = host.ExecuteControlTransfer(setupPacket, null, 0, deviceAddress); }
public UsbCbiTransport(IUsbHost host, int deviceAddress) { var device = host.GetConnectedDeviceInfo((byte)deviceAddress); if (device == null) { throw new InvalidOperationException($"There's no device connected with address {deviceAddress}"); } //HACK: Detect Konamiman's Traxdata FDD by VID+PID, //since it's a fully compliant CBI+UFI FDD but it identifies itself with class = FFh UsbInterface iface; if (device.VendorId == 0x0644 && device.ProductId == 1) { iface = device.InterfacesForCurrentConfiguration.First(); } else { iface = device.InterfacesForCurrentConfiguration.Where(i => i.Class == 8 && i.Subclass == 4 && i.Protocol == 0) .SingleOrDefault(); } if (iface == null) { throw new InvalidOperationException("The device does not implement mass storage with the CBI transport on any of the interfaces for the current configuration"); } this.deviceAddress = deviceAddress; this.host = host; bulkInEndpoint = iface.Endpoints.Where(e => e.Type == UsbEndpointType.Bulk && e.DataDirection == UsbDataDirection.IN).First(); bulkOutEndpoint = iface.Endpoints.Where(e => e.Type == UsbEndpointType.Bulk && e.DataDirection == UsbDataDirection.OUT).First(); interruptEndpoint = iface.Endpoints.Where(e => e.Type == UsbEndpointType.Interrupt).First(); adsc = new UsbSetupPacket(0, 0x21); adsc.wIndexL = iface.InterfaceNumber; }
void InitializeHub() { const byte PortNumber = 1; // Set address and configure hub var data = new byte[255]; byte endpointZeroMaxPacketSize = 8; var result = GetDescriptor(0, UsbDescriptorType.DEVICE, 0, 0, endpointZeroMaxPacketSize, out data); if (result.IsError) { throw new UsbTransferException($"When getting hub descriptor: {result.TransactionResult}", result.TransactionResult); } if (data[4] != 9) { return; } //throw new UsbTransferException("Not a hub!", UsbPacketResult.Ok); endpointZeroMaxPacketSize = data[7]; var setAddressSetupPacket = new UsbSetupPacket(UsbStandardRequest.SET_ADDRESS, 0); setAddressSetupPacket.wValue = UsbHubAddress; result = hw.ExecuteControlTransfer(setAddressSetupPacket, null, 0, 0, endpointZeroMaxPacketSize); if (result.IsError) { throw new UsbTransferException($"When setting hub address: {result.TransactionResult}", result.TransactionResult); } var setConfigSetupPacket = new UsbSetupPacket(UsbStandardRequest.SET_CONFIGURATION, 0); setConfigSetupPacket.wValueL = 1; //bConfigurationValue result = hw.ExecuteControlTransfer(setConfigSetupPacket, null, 0, UsbHubAddress, endpointZeroMaxPacketSize); if (result.IsError) { throw new UsbTransferException($"When setting hub configuration: {result.TransactionResult}", result.TransactionResult); } // Power port 1 var setPortFeatureSetupPacket = new UsbSetupPacket(3, 0b00100011); //SET_FEATURE for port setPortFeatureSetupPacket.wValue = 8; //PORT_POWER setPortFeatureSetupPacket.wIndex = PortNumber; result = hw.ExecuteControlTransfer(setPortFeatureSetupPacket, null, 0, UsbHubAddress, endpointZeroMaxPacketSize); if (result.IsError) { throw new UsbTransferException($"When powering port: {result.TransactionResult}", result.TransactionResult); } // Reset port 1 var resetDeviceOnPortSetupPacket = new UsbSetupPacket(3, 0b00100011); //SET_FEATURE for port resetDeviceOnPortSetupPacket.wValue = 4; //PORT_RESET resetDeviceOnPortSetupPacket.wIndex = PortNumber; result = hw.ExecuteControlTransfer(resetDeviceOnPortSetupPacket, null, 0, UsbHubAddress, endpointZeroMaxPacketSize); if (result.IsError) { throw new UsbTransferException($"When resetting device on port: {result.TransactionResult}", result.TransactionResult); } Thread.Sleep(100); //Wait for reset to complete }
private UsbPacketResult InitializeDevice() { byte[] data = new byte[255]; UsbTransferResult result; UsbSetupPacket getDescriptorSetupPacket = new UsbSetupPacket(UsbStandardRequest.GET_DESCRIPTOR, 0x80); byte endpointZeroMaxPacketSize = 8; //InitializeHub(); //Here device is in DEFAULT state (hw did bus reset already): result = GetDescriptor(0, UsbDescriptorType.DEVICE, 0, 0, endpointZeroMaxPacketSize, out data); if (result.IsError) { throw new UsbTransferException($"When getting device descriptor: {result.TransactionResult}", result.TransactionResult); } endpointZeroMaxPacketSize = data[7]; var deviceDescriptorBytes = data.Take(result.TransferredDataCount).ToArray(); var setAddressSetupPacket = new UsbSetupPacket(UsbStandardRequest.SET_ADDRESS, 0); setAddressSetupPacket.wValue = UsbDeviceAddress; result = hw.ExecuteControlTransfer(setAddressSetupPacket, null, 0, 0, endpointZeroMaxPacketSize); if (result.IsError) { throw new UsbTransferException($"When setting device address: {result.TransactionResult}", result.TransactionResult); } //Here device is in ADDRESS state getDescriptorSetupPacket.wValueH = UsbDescriptorType.CONFIGURATION; getDescriptorSetupPacket.wValueL = 0; //We're interested in the first pconfiguration available getDescriptorSetupPacket.wLength = (short)data.Length; result = GetDescriptor(UsbDeviceAddress, UsbDescriptorType.CONFIGURATION, 0, 0, endpointZeroMaxPacketSize, out data); if (result.IsError) { throw new UsbTransferException($"When getting configuration descriptor: {result.TransactionResult}", result.TransactionResult); } var bConfigurationValue = data[5]; var configurationDescriptorLength = result.TransferredDataCount; var setConfigSetupPacket = new UsbSetupPacket(UsbStandardRequest.SET_CONFIGURATION, 0); setConfigSetupPacket.wValueL = bConfigurationValue; result = hw.ExecuteControlTransfer(setConfigSetupPacket, null, 0, UsbDeviceAddress, endpointZeroMaxPacketSize); if (result.IsError) { throw new UsbTransferException($"When setting device configuration: {result.TransactionResult}", result.TransactionResult); } //Here device is in CONFIGURED state var interfacesInfo = GetInterfacesInfo(data.Take(configurationDescriptorLength).ToArray()); connectedDevice = new UsbConnectedDevice( endpointZeroMaxPacketSize, deviceDescriptorBytes[4], deviceDescriptorBytes[5], deviceDescriptorBytes[6], (int)(deviceDescriptorBytes[8] | (deviceDescriptorBytes[9] << 8)), (int)(deviceDescriptorBytes[10] | (deviceDescriptorBytes[11] << 8)), deviceDescriptorBytes[14], deviceDescriptorBytes[15], interfacesInfo); return(UsbPacketResult.Ok); }