Пример #1
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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;
        }
Пример #7
0
        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
        }
Пример #8
0
        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);
        }