/// <summary>
        /// Builds an interface-selection request.
        /// </summary>
        /// <param name="configuration">The result of configuration-selection.</param>
        /// <param name="index">The index of the interface to be selected.</param>
        /// <returns>The interface-selection request.</returns>
        public TS_URB_SELECT_INTERFACE BuildSelectionInterfaceRequest(TS_URB_SELECT_CONFIGURATION_RESULT configuration, int index)
        {
            if (null == configuration)
            {
                throw new ArgumentNullException("configuration");
            }
            if (index >= configuration.Interface.Length || null == configuration.Interface[index])
            {
                throw new ArgumentException("index specified interface doesn't exist.");
            }

            TS_URB_SELECT_INTERFACE urb = new TS_URB_SELECT_INTERFACE(this.requestId, this.noAck);

            urb.ConfigurationHandle = configuration.ConfigurationHandle;
            urb.Header.Size         = 8 + 4; // Header + ConfigurationHandle
            urb.TsUsbdIInfo         = new TS_USBD_INTERFACE_INFORMATION();
            TS_USBD_INTERFACE_INFORMATION_RESULT inf = configuration.Interface[index];

            if (inf.NumberOfPipes != inf.Pipes.Length)
            {
                throw new ArgumentException(String.Format(
                                                "The selecting interface count doesn't match. NumberOfPipes: {0}, Pipes count: {1}.",
                                                inf.NumberOfPipes,
                                                inf.Pipes.Length
                                                ));
            }

            urb.TsUsbdIInfo.Length = 2 + 2 + 1 + 1 + 2 + 4;
            urb.TsUsbdIInfo.NumberOfPipesExpected = (ushort)inf.NumberOfPipes;
            urb.TsUsbdIInfo.InterfaceNumber       = inf.InterfaceNumber;
            urb.TsUsbdIInfo.AlternateSetting      = inf.AlternateSetting;
            urb.TsUsbdIInfo.Padding       = PaddingGenerator.GeneratePadding();
            urb.TsUsbdIInfo.NumberOfPipes = inf.NumberOfPipes;

            urb.TsUsbdIInfo.Infomations = new TS_USBD_PIPE_INFORMATION[inf.NumberOfPipes];
            for (int i = 0; i < inf.NumberOfPipes; i++)
            {
                urb.TsUsbdIInfo.Length        += 2 + 2 + 4 + 4; // count Pipe sizes
                urb.TsUsbdIInfo.Infomations[i] = new TS_USBD_PIPE_INFORMATION();
                urb.TsUsbdIInfo.Infomations[i].MaximumPacketSize   = inf.Pipes[i].MaximumPacketSize;
                urb.TsUsbdIInfo.Infomations[i].Padding             = PaddingGenerator.GeneratePadding();
                urb.TsUsbdIInfo.Infomations[i].MaximumTransferSize = inf.Pipes[i].MaximumTransferSize;
                urb.TsUsbdIInfo.Infomations[i].PipeFlags           = inf.Pipes[i].PipeFlags;
            }

            urb.Header.Size += urb.TsUsbdIInfo.Length; // interface information size.
            return(urb);
        }
Пример #2
0
        public TS_URB ParsePdu(byte[] data)
        {
            TS_URB urb;

            switch (GetTsUrbType(data))
            {
            // Indicates to the host controller driver that a configuration is to be selected
            case URB_FUNCTIONID.URB_FUNCTION_SELECT_CONFIGURATION:
                urb = new TS_URB_SELECT_CONFIGURATION();
                break;

            // Indicates to the host controller driver that an alternate interface setting is being selected for an interface.
            // If set, the URB is used with _URB_SELECT_INTERFACE as the data structure.
            case URB_FUNCTIONID.URB_FUNCTION_SELECT_INTERFACE:
                urb = new TS_URB_SELECT_INTERFACE();
                break;

            // Indicates that all outstanding requests for a pipe should be canceled.
            case URB_FUNCTIONID.URB_FUNCTION_ABORT_PIPE:

            // Resets the indicated pipe.
            case URB_FUNCTIONID.URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:

            // Clears the halt condition on the host side of a pipe.
            // If set, this URB is used with _URB_PIPE_REQUEST as the data structure.
            case URB_FUNCTIONID.URB_FUNCTION_SYNC_RESET_PIPE:

            // Clears the stall condition on the endpoint. For all pipes except isochronous pipes.
            case URB_FUNCTIONID.URB_FUNCTION_SYNC_CLEAR_STALL:
                urb = new TS_URB_PIPE_REQUEST();
                break;

            // Requests the current frame number from the host controller driver.
            case URB_FUNCTIONID.URB_FUNCTION_GET_CURRENT_FRAME_NUMBER:
                urb = new TS_URB_GET_CURRENT_FRAME_NUMBER();
                break;

            // Transfers data to or from a control pipe.
            case URB_FUNCTIONID.URB_FUNCTION_CONTROL_TRANSFER:
                urb = new TS_URB_CONTROL_TRANSFER();
                break;

            // Transfers data from a bulk pipe or interrupt pipe or to an bulk pipe.
            case URB_FUNCTIONID.URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
                urb = new TS_URB_BULK_OR_INTERRUPT_TRANSFER();
                break;

            // Transfers data to or from an isochronous pipe.
            case URB_FUNCTIONID.URB_FUNCTION_ISOCH_TRANSFER:
                urb = new TS_URB_ISOCH_TRANSFER();
                break;

            // Retrieves the device descriptor from a specific USB device.
            case URB_FUNCTIONID.URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:

            // Retrieves the descriptor from an endpoint on an interface for a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT:

            // Sets a device descriptor on a device.
            case URB_FUNCTIONID.URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE:

            // Sets an endpoint descriptor on an endpoint for an interface.
            case URB_FUNCTIONID.URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT:

            // Retrieves the descriptor from an interface for a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:

            // Sets a descriptor for an interface on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE:
                urb = new TS_URB_CONTROL_DESCRIPTOR_REQUEST();
                break;

            // Sets a USB-defined feature on a device.
            case URB_FUNCTIONID.URB_FUNCTION_SET_FEATURE_TO_DEVICE:

            // Sets a USB-defined feature on an endpoint for an interface on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_SET_FEATURE_TO_ENDPOINT:

            // Sets a USB-defined feature on an interface for a device.
            case URB_FUNCTIONID.URB_FUNCTION_SET_FEATURE_TO_INTERFACE:

            // Sets a USB-defined feature on a device-defined target on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_SET_FEATURE_TO_OTHER:

            // Clears a USB-defined feature on a device.
            case URB_FUNCTIONID.URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE:

            // Clears a USB-defined feature on an endpoint, for an interface, on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT:

            // Clears a USB-defined feature on an interface for a device.
            case URB_FUNCTIONID.URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE:

            // Clears a USB-defined feature on a device defined target on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_CLEAR_FEATURE_TO_OTHER:
                urb = new TS_URB_CONTROL_FEATURE_REQUEST();
                break;

            // Retrieves status from a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_GET_STATUS_FROM_DEVICE:

            // Retrieves status from an endpoint for an interface on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_GET_STATUS_FROM_ENDPOINT:

            // Retrieves status from an interface on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_GET_STATUS_FROM_INTERFACE:

            // Retrieves status from a device-defined target on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_GET_STATUS_FROM_OTHER:
                urb = new TS_URB_CONTROL_GET_STATUS_REQUEST();
                break;

            // Sends a vendor-specific command to a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_VENDOR_DEVICE:

            // Sends a vendor-specific command for an endpoint on an interface on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_VENDOR_ENDPOINT:

            // Sends a vendor-specific command for an interface on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_VENDOR_INTERFACE:

            // Sends a vendor-specific command to a device-defined target on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_VENDOR_OTHER:

            // Sends a USB-defined class-specific command to a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_CLASS_DEVICE:

            // Sends a USB-defined class-specific command to an endpoint, on an interface, on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_CLASS_ENDPOINT:

            // Sends a USB-defined class-specific command to an interface on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_CLASS_INTERFACE:

            // Sends a USB-defined class-specific command to a device defined target on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_CLASS_OTHER:
                urb = new TS_URB_CONTROL_VENDOR_OR_CLASS_REQUEST();
                break;

            // Retrieves the current configuration on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_GET_CONFIGURATION:
                urb = new TS_URB_CONTROL_GET_CONFIGURATION_REQUEST();
                break;

            // Retrieves the current settings for an interface on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_GET_INTERFACE:
                urb = new TS_URB_CONTROL_GET_INTERFACE_REQUEST();
                break;

            // Retrieves a Microsoft OS feature descriptor from a USB device or an interface on a USB device.
            case URB_FUNCTIONID.URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR:
                urb = new TS_URB_OS_FEATURE_DESCRIPTOR_REQUEST();
                break;

            // Transfers data to or from a control pipe without a time limit specified by a timeout value.
            case URB_FUNCTIONID.URB_FUNCTION_CONTROL_TRANSFER_EX:
                urb = new TS_URB_CONTROL_TRANSFER_EX();
                break;

            default:
                urb = new TS_URB_UNKNOWN();
                break;
            }

            if (!PduMarshaler.Unmarshal(data, urb))
            {
                urb = new TS_URB_UNKNOWN();
                PduMarshaler.Unmarshal(data, urb);
            }
            return(urb);
        }