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;
        }
Example #2
0
        //Descriptors appear concatenated as follows:
        //  configuration descriptor
        //    interface 0, alt setting 0 descriptor
        //      endpoint 0 for interface 0 alt setting 0 descriptor
        //      endpoint 1 for interface 0 alt setting 0 descriptor
        //    interface 0, alt setting 1 descriptor
        //      endpoint 0 for interface 0 alt setting 1 descriptor
        //      endpoint 1 for interface 0 alt setting 1 descriptor
        //    interface 1, alt setting 0 descriptor
        //      endpoint 0 for interface 1 alt setting 0 descriptor
        //      endpoint 1 for interface 1 alt setting 0 descriptor
        //    interface 2, alt setting 0 descriptor
        //      endpoint 0 for interface 2 alt setting 0 descriptor
        //      endpoint 1 for interface 2 alt setting 0 descriptor
        private UsbInterface[] GetInterfacesInfo(byte[] configurationDescriptor)
        {
            var remainingDescriptorBytes = configurationDescriptor;

            void GoToNextDescriptor()
            {
                if (remainingDescriptorBytes.Length > 0)
                {
                    remainingDescriptorBytes = remainingDescriptorBytes.Skip(remainingDescriptorBytes[0]).ToArray();
                }
            }

            byte DescriptorByteAt(int index) => remainingDescriptorBytes[index];

            var interfacesCount = DescriptorByteAt(4);
            var interfaces      = new UsbInterface[interfacesCount];

            GoToNextDescriptor();   //1st interface descriptor

            for (var interfaceIndex = 0; interfaceIndex < interfacesCount; interfaceIndex++)
            {
                var endpointsCount        = DescriptorByteAt(4);
                var alternateSettingIndex = DescriptorByteAt(3);

                //TODO: Add support for alternate settings
                if (alternateSettingIndex != 0)
                {
                    GoToNextDescriptor();   //1st endpoint descriptor
                    for (int i = 0; i < endpointsCount; i++)
                    {
                        GoToNextDescriptor();   //Next endpoint descriptor
                    }
                    continue;
                }

                var interfaceNumber = DescriptorByteAt(2);
                var @class          = DescriptorByteAt(5);
                var subclass        = DescriptorByteAt(6);
                var protocol        = DescriptorByteAt(7);

                var endpoints = new UsbEndpoint[endpointsCount];

                GoToNextDescriptor();   //1st endpoint descriptor

                for (var endpointIndex = 0; endpointIndex < endpointsCount; endpointIndex++)
                {
                    endpoints[endpointIndex] = new UsbEndpoint(
                        number: DescriptorByteAt(2),
                        type: (UsbEndpointType)DescriptorByteAt(3),
                        maxPacketSize: DescriptorByteAt(4) | DescriptorByteAt(5));

                    GoToNextDescriptor();   //Next endpoint descriptor
                }

                interfaces[interfaceIndex] = new UsbInterface(interfaceNumber, @class, subclass, protocol, endpoints);

                GoToNextDescriptor();   //Next interface descriptor
            }

            return(interfaces.Where(i => i != null).ToArray());
        }