/// <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); }
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); }