コード例 #1
0
ファイル: USBManager.cs プロジェクト: rmhasan/FlingOS
        /// <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;
        }
コード例 #2
0
ファイル: USBManager.cs プロジェクト: rmhasan/FlingOS
 private static void ShowConfiguration(Configuration d)
 {
     DBGMSG(((FOS_System.String)"Number of interfaces: ") + d.NumInterfaces);
     DBGMSG(((FOS_System.String)"ID of config:         ") + d.Selector);
     if (d.Description != null)
     {
         DBGMSG(((FOS_System.String)"Description:          ") + d.Description.Value);
     }
     else
     {
         DBGMSG("Description:          [NONE]");
     }
     DBGMSG(((FOS_System.String)"Remote wakeup:        ") + (((d.Attribs & Configuration.Attributes.RemoteWakeup) != 0) ? "Yes" : "No"));
     DBGMSG(((FOS_System.String)"Self-powered:         ") + (((d.Attribs & Configuration.Attributes.SelfPowered) != 0) ? "Yes" : "No"));
     DBGMSG(((FOS_System.String)"Max power (mA):       ") + d.MaxPower * 2); // 2 mA steps used
     BasicConsole.DelayOutput(1);
 }