Beispiel #1
0
        /// <summary>
        /// Gets the configuration descriptor from the specified device.
        /// </summary>
        /// <param name="device">The device info of the device to get the descriptor from.</param>
        /// <returns>True if USB transfer completed successfully. Otherwise, false.</returns>
        public static unsafe bool GetConfigurationDescriptors(USBDeviceInfo device)
        {
#if USB_TRACE
            DBGMSG("USB: GET_DESCRIPTOR Config");
#endif

            //64 byte buffer
            ushort bufferSize = 64;
            byte* buffer = (byte*)FOS_System.Heap.AllocZeroed(bufferSize, "USBManager: GetConfigDescriptor");

            bool success = false;

            try
            {
                USBTransfer transfer = new USBTransfer();
                device.hc.SetupTransfer(device, transfer, USBTransferType.Control, 0, bufferSize);
                device.hc.SETUPTransaction(transfer, 8, 0x80, 6, 2, 0, 0, bufferSize);
                device.hc.INTransaction(transfer, false, buffer, 64);
                device.hc.OUTTransaction(transfer, true, null, 0);
                device.hc.IssueTransfer(transfer);

                success = transfer.success;

                if (transfer.success)
                {
                    byte currentConfig = GetConfiguration(device);

                    // parse to config (len=9,type=2), interface (len=9,type=4) or endpoint (len=7,type=5)
#if USB_TRACE
                    DBGMSG("---------------------------------------------------------------------");
#endif
                    byte* addr = buffer;
                    byte* lastByte = addr + bufferSize;

                    ushort numEndpoints = 1;
                    // First pass. Retrieve usb_interfaceDescriptor which contains the number of endpoints
                    while (addr < lastByte)
                    {
                        byte type = *(addr + 1);
                        byte length = *addr;

                        if (length == 9 && type == 2)
                        {
                            ConfigurationDescriptor* descriptor = (ConfigurationDescriptor*)addr;

                            Configuration config = new Configuration();
                            config.Attribs = (Configuration.Attributes)descriptor->attributes;
                            config.Selector = descriptor->configurationValue;
                            config.MaxPower = descriptor->maxPower;
                            config.NumInterfaces = descriptor->numInterfaces;
                            if (currentConfig == config.Selector)
                            {
                                config.Description = GetUnicodeStringDescriptor(device, descriptor->configuration);
                            }
                            else
                            {
                                config.Description = new UnicodeString() { StringType = 0, Value = "[Unable to load at this time]" };
                            }

                            device.Configurations.Add(config);

#if USB_TRACE
                            ShowConfiguration(config);
#endif
                        }
                        else if (length == 9 && type == 4)
                        {
                            InterfaceDescriptor* descriptor = (InterfaceDescriptor*)addr;

                            Interface interf = new Interface();
                            interf.InterfaceNumber = descriptor->interfaceNumber;
                            interf.AlternateSetting = descriptor->alternateSetting;
                            interf.Class = descriptor->interfaceClass;
                            interf.Subclass = descriptor->interfaceSubclass;
                            interf.Protocol = descriptor->interfaceProtocol;
                            interf.Description = GetUnicodeStringDescriptor(device, descriptor->StringIndex);
                            interf.NumEndpoints = descriptor->numEndpoints;
                            device.Interfaces.Add(interf);

#if USB_TRACE
                            ShowInterface(interf);
#endif

                            if (interf.Class == 8)
                            {
                                // store interface number for mass storage transfers
                                device.MSD_InterfaceNum = interf.InterfaceNumber;
                                device.InterfaceClass = interf.Class;
                                device.InterfaceSubclass = interf.Subclass;
                            }

                            numEndpoints += interf.NumEndpoints;
                        }
                        else if (length == 7 && type == 5)
                        {
                            //Skip endpoints in first pass
                        }
                        else
                        {
#if USB_TRACE
                            DBGMSG(((FOS_System.String)"Unknown descriptor: Length=") + length + ", Type=" + type);
#endif
                            if (length == 0)
                            {
                                break;
                            }
                        }
                        addr += length;
                    }

                    FOS_System.Object endpointZero = device.Endpoints[0];
                    device.Endpoints.Empty();
                    device.Endpoints.Add(endpointZero);
                    for (int i = 0; i < numEndpoints - 1; i++)
                    {
                        device.Endpoints.Add(new Endpoint());
                    }

                    // Second pass. Fill in endpoint information
                    addr = buffer;
                    while (addr < lastByte)
                    {
                        byte type = *(addr + 1);
                        byte length = *addr;

                        if (length == 7 && type == 5)
                        {
                            EndpointDescriptor* descriptor = (EndpointDescriptor*)addr;

                            byte ep_id = (byte)(descriptor->endpointAddress & 0xF);
#if USB_TRACE
                            if (ep_id >= numEndpoints)
                            {
                                DBGMSG("ep_id >= numEndpoints!!");
                            }
#endif
                            Endpoint endpoint = (Endpoint)device.Endpoints[ep_id];

                            endpoint.MPS = descriptor->maxPacketSize;
                            endpoint.Type = Endpoint.Types.BIDIR; // Can be overwritten below
                            endpoint.Address = (byte)(descriptor->endpointAddress & 0xF);
                            endpoint.Attributes = descriptor->attributes;
                            endpoint.Interval = descriptor->interval;

                            // store endpoint numbers for IN/OUT mass storage transfers, attributes must be 0x2, because there are also endpoints with attributes 0x3(interrupt)
                            if ((descriptor->endpointAddress & 0x80) > 0 && descriptor->attributes == 0x2)
                            {
                                if (ep_id < 3)
                                {
                                    device.MSD_INEndpointID = ep_id;
                                }
                                endpoint.Type = Endpoint.Types.IN;
                            }

                            if ((descriptor->endpointAddress & 0x80) == 0 && descriptor->attributes == 0x2)
                            {
                                if (ep_id < 3)
                                {
                                    device.MSD_OUTEndpointID = ep_id;
                                }
                                endpoint.Type = Endpoint.Types.OUT;
                            }

#if USB_TRACE
                            ShowEndpoint(endpoint);
#endif
                        }
                        else if (length == 0)
                        {
                            break;
                        }

                        addr += length;
                    }
                }
            }
            finally
            {
                FOS_System.Heap.Free(buffer);
            }

            return success;
        }
Beispiel #2
0
        private static void ShowInterface(Interface d)
        {
            DBGMSG("---------------------------------------------------------------------");
                
            switch (d.NumEndpoints)
            {
                case 0:
                    DBGMSG(((FOS_System.String)"Interface ") + d.InterfaceNumber + " has no endpoint and belongs to class:");
                    break;
                case 1:
                    DBGMSG(((FOS_System.String)"Interface ") + d.InterfaceNumber + " has only one endpoint and belongs to class:");
                    break;
                default:
                    DBGMSG(((FOS_System.String)"Interface ") + d.InterfaceNumber + " has " + d.NumEndpoints + " endpoints and belongs to class:");
                    break;
            }

            switch (d.Class)
            {
                case 0x01:
                    DBGMSG("Audio");
                    break;
                case 0x02:
                    DBGMSG("Communications and CDC Control");
                    break;
                case 0x03:
                    DBGMSG("HID (Human Interface Device)");
                    break;
                case 0x05:
                    DBGMSG("Physical");
                    break;
                case 0x06:
                    DBGMSG("Image");
                    break;
                case 0x07:
                    DBGMSG("Printer");
                    break;
                case 0x08:
                    DBGMSG("Mass Storage, ");
                    switch (d.Subclass)
                    {
                        case 0x01:
                            DBGMSG("Reduced Block Commands, ");
                            break;
                        case 0x02:
                            DBGMSG("SFF-8020i or MMC-2(ATAPI), ");
                            break;
                        case 0x03:
                            DBGMSG("QIC-157 (tape device), ");
                            break;
                        case 0x04:
                            DBGMSG("UFI (e.g. Floppy Disk), ");
                            break;
                        case 0x05:
                            DBGMSG("SFF-8070i (e.g. Floppy Disk), ");
                            break;
                        case 0x06:
                            DBGMSG("SCSI transparent command set, ");
                            break;
                    }
                    switch (d.Protocol)
                    {
                        case 0x00:
                            DBGMSG("CBI protocol with command completion interrupt.");
                            break;
                        case 0x01:
                            DBGMSG("CBI protocol without command completion interrupt.");
                            break;
                        case 0x50:
                            DBGMSG("Bulk-Only Transport protocol.");
                            break;
                    }
                    break;
                case 0x0A:
                    DBGMSG("CDC-Data");
                    break;
                case 0x0B:
                    DBGMSG("Smart Card");
                    break;
                case 0x0D:
                    DBGMSG("Content Security");
                    break;
                case 0x0E:
                    DBGMSG("Video");
                    break;
                case 0x0F:
                    DBGMSG("Personal Healthcare");
                    break;
                case 0xDC:
                    DBGMSG("Diagnostic Device");
                    break;
                case 0xE0:
                    DBGMSG(((FOS_System.String)"Wireless Controller, subclass: ") + d.Subclass + " protocol: " + d.Protocol + ".");
                    break;
                case 0xEF:
                    DBGMSG("Miscellaneous");
                    break;
                case 0xFE:
                    DBGMSG("Application Specific");
                    break;
                case 0xFF:
                    DBGMSG("Vendor Specific");
                    break;
            }

            DBGMSG(((FOS_System.String)"Alternate Setting:  ") + d.AlternateSetting);
            DBGMSG(((FOS_System.String)"Class:              ") + d.Class);
            DBGMSG(((FOS_System.String)"Subclass:           ") + d.Subclass);
            DBGMSG(((FOS_System.String)"Protocol:           ") + d.Protocol);
            if (d.Description != null)
            {
                DBGMSG(((FOS_System.String)"Description:        ") + d.Description.Value);
            }
            else
            {
                DBGMSG("Description:        [NONE]");
            }
            BasicConsole.DelayOutput(1);
        }