Integrate the USBKit into libdevice and make it public. I left the USBKit.h
name, as it in fact is like a kit in the kit. It combines the different BUSB* classes as compared to SerialPort.h where there really is a 1:1 relationship between the header and the (one) class. If someone has a better fitting name please shout. Separated the usb_raw.h into usb_raw.h which defines the protocol and usb_raw_private.h which holds the internal device structure for usb_raw. This reduces the header dependencies. Hopefully cought all occurencies of USBKit.a usage (in usb_dev_info and the usb_webcam media add-on) but might have missed something that is not in the image. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24858 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
* Copyright 2007-2008, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef _USBKIT_H
|
||||
#define _USBKIT_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <USB3.h>
|
||||
#include <USB_spec.h>
|
||||
|
||||
|
||||
class BUSBRoster;
|
||||
class BUSBDevice;
|
||||
class BUSBConfiguration;
|
||||
class BUSBInterface;
|
||||
class BUSBEndpoint;
|
||||
|
||||
|
||||
/* The BUSBRoster class can be used to watch for devices that get attached or
|
||||
removed from the USB bus.
|
||||
You subclass the roster and implement the pure virtual DeviceAdded() and
|
||||
DeviceRemoved() hooks. */
|
||||
class BUSBRoster {
|
||||
public:
|
||||
BUSBRoster();
|
||||
virtual ~BUSBRoster();
|
||||
|
||||
// The DeviceAdded() hook will be called when a new device gets
|
||||
// attached to the USB bus. The hook is called with an initialized
|
||||
// BUSBDevice object. If you return B_OK from your hook the object
|
||||
// will stay valid and the DeviceRemoved() hook will be called with
|
||||
// for it. Otherwise the object is deleted and DeviceRemoved()
|
||||
// is not called.
|
||||
virtual status_t DeviceAdded(BUSBDevice *device) = 0;
|
||||
|
||||
// When a device gets detached from the bus that you hold a
|
||||
// BUSBDevice object for (gotten through DeviceAdded()) the
|
||||
// DeviceRemoved() hook will be called. The device object gets
|
||||
// invalid and will be deleted as soon as you return from the hook
|
||||
// so be sure to remove all references to it.
|
||||
virtual void DeviceRemoved(BUSBDevice *device) = 0;
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
virtual void _ReservedUSBRoster1();
|
||||
virtual void _ReservedUSBRoster2();
|
||||
virtual void _ReservedUSBRoster3();
|
||||
virtual void _ReservedUSBRoster4();
|
||||
virtual void _ReservedUSBRoster5();
|
||||
|
||||
void *fLooper;
|
||||
uint32 fReserved[10];
|
||||
};
|
||||
|
||||
|
||||
/* The BUSBDevice presents an interface to USB device. You can either get
|
||||
it through the BUSBRoster or by creating one yourself and setting it to
|
||||
a valid raw usb device (with a path of "/dev/bus/usb/x").
|
||||
The device class provides direct accessors for descriptor fields as well
|
||||
as convenience functions to directly get string representations of fields.
|
||||
The BUSBDevice also provides access for the BUSBConfiguration objects of
|
||||
a device. These objects and all of their child objects depend on the
|
||||
parent device and will be deleted as soon as the device object is
|
||||
destroyed */
|
||||
class BUSBDevice {
|
||||
public:
|
||||
BUSBDevice(const char *path = NULL);
|
||||
virtual ~BUSBDevice();
|
||||
|
||||
virtual status_t InitCheck();
|
||||
|
||||
status_t SetTo(const char *path);
|
||||
void Unset();
|
||||
|
||||
// Returns the location on the bus represented as hub/device sequence
|
||||
const char *Location() const;
|
||||
bool IsHub() const;
|
||||
|
||||
// These are direct accessors to descriptor fields
|
||||
uint16 USBVersion() const;
|
||||
uint8 Class() const;
|
||||
uint8 Subclass() const;
|
||||
uint8 Protocol() const;
|
||||
uint8 MaxEndpoint0PacketSize() const;
|
||||
uint16 VendorID() const;
|
||||
uint16 ProductID() const;
|
||||
uint16 Version() const;
|
||||
|
||||
// The string functions return the string representation of the
|
||||
// descriptor data. The strings are decoded to normal 0 terminated
|
||||
// c strings and are cached and owned by the object.
|
||||
// If a string is not available an empty string is returned.
|
||||
const char *ManufacturerString() const;
|
||||
const char *ProductString() const;
|
||||
const char *SerialNumberString() const;
|
||||
|
||||
const usb_device_descriptor *Descriptor() const;
|
||||
|
||||
// GetStringDescriptor() can be used to retrieve the raw
|
||||
// usb_string_descriptor with a given index. The strings contained
|
||||
// in these descriptors are usually two-byte unicode encoded.
|
||||
size_t GetStringDescriptor(uint32 index,
|
||||
usb_string_descriptor *descriptor,
|
||||
size_t length) const;
|
||||
|
||||
// Use the DecodeStringDescriptor() convenience function to get a
|
||||
// 0-terminated c string for a given string index. Note that this
|
||||
// will allocate the string as "new char[];" and needs to be deleted
|
||||
// like "delete[] string;" by the caller.
|
||||
char *DecodeStringDescriptor(uint32 index) const;
|
||||
|
||||
size_t GetDescriptor(uint8 type, uint8 index,
|
||||
uint16 languageID, void *data,
|
||||
size_t length) const;
|
||||
|
||||
// With ConfigurationAt() or ActiveConfiguration() you can get an
|
||||
// object that represents the configuration at a certain index or at
|
||||
// the index that is currently configured. Note that the index does not
|
||||
// necessarily correspond with the configuration value.
|
||||
// Use the returned object as an argument to SetConfiguration() to
|
||||
// change the active configuration of a device.
|
||||
uint32 CountConfigurations() const;
|
||||
const BUSBConfiguration *ConfigurationAt(uint32 index) const;
|
||||
|
||||
const BUSBConfiguration *ActiveConfiguration() const;
|
||||
status_t SetConfiguration(
|
||||
const BUSBConfiguration *configuration);
|
||||
|
||||
// ControlTransfer() sends requests using the default pipe
|
||||
ssize_t ControlTransfer(uint8 requestType,
|
||||
uint8 request, uint16 value,
|
||||
uint16 index, uint16 length,
|
||||
void *data) const;
|
||||
|
||||
private:
|
||||
virtual void _ReservedUSBDevice1();
|
||||
virtual void _ReservedUSBDevice2();
|
||||
virtual void _ReservedUSBDevice3();
|
||||
virtual void _ReservedUSBDevice4();
|
||||
virtual void _ReservedUSBDevice5();
|
||||
|
||||
char *fPath;
|
||||
int fRawFD;
|
||||
|
||||
usb_device_descriptor fDescriptor;
|
||||
BUSBConfiguration **fConfigurations;
|
||||
uint32 fActiveConfiguration;
|
||||
|
||||
mutable char *fManufacturerString;
|
||||
mutable char *fProductString;
|
||||
mutable char *fSerialNumberString;
|
||||
|
||||
uint32 fReserved[10];
|
||||
};
|
||||
|
||||
|
||||
/* A BUSBConfiguration object represents one of possibly multiple
|
||||
configurations a device might have. A valid object can only be gotten
|
||||
through the ConfigurationAt() and ActiveConfiguration() methods of a
|
||||
BUSBDevice.
|
||||
The BUSBConfiguration provides further access into the configuration by
|
||||
providing CountInterfaces() and InterfaceAt() to retrieve BUSBInterface
|
||||
objects. */
|
||||
class BUSBConfiguration {
|
||||
public:
|
||||
// Device() returns the parent device of this configuration. This
|
||||
// configuration is located at the index returned by Index() within
|
||||
// that parent device.
|
||||
uint32 Index() const;
|
||||
const BUSBDevice *Device() const;
|
||||
|
||||
// Gets a describing string of this configuration if available.
|
||||
// Otherwise an empty string is returned.
|
||||
const char *ConfigurationString() const;
|
||||
|
||||
const usb_configuration_descriptor
|
||||
*Descriptor() const;
|
||||
|
||||
// With CountInterfaces() and InterfaceAt() you can iterate through
|
||||
// the child interfaces of this configuration. It is the only valid
|
||||
// way to get a BUSBInterface object.
|
||||
// Note that the interface objects retrieved using InterfaceAt() will
|
||||
// be invalid and deleted as soon as this configuration gets deleted.
|
||||
uint32 CountInterfaces() const;
|
||||
const BUSBInterface *InterfaceAt(uint32 index) const;
|
||||
|
||||
private:
|
||||
friend class BUSBDevice;
|
||||
BUSBConfiguration(BUSBDevice *device,
|
||||
uint32 index, int rawFD);
|
||||
~BUSBConfiguration();
|
||||
|
||||
BUSBDevice *fDevice;
|
||||
uint32 fIndex;
|
||||
int fRawFD;
|
||||
|
||||
usb_configuration_descriptor fDescriptor;
|
||||
BUSBInterface **fInterfaces;
|
||||
|
||||
mutable char *fConfigurationString;
|
||||
|
||||
uint32 fReserved[10];
|
||||
};
|
||||
|
||||
|
||||
/* The BUSBInterface class can be used to access the descriptor fields of
|
||||
an underleying USB interface. Most importantly though it can be used to
|
||||
iterate over and retrieve BUSBEndpoint objects that can be used to
|
||||
transfer data over the bus. */
|
||||
class BUSBInterface {
|
||||
public:
|
||||
// Configuration() returns the parent configuration of this interface.
|
||||
// This interface is located at the index returned by Index() in that
|
||||
// parent configuration.
|
||||
// Device() is a convenience function to directly reach the parent
|
||||
// device of this interface instead of going through the configuration.
|
||||
uint32 Index() const;
|
||||
const BUSBConfiguration *Configuration() const;
|
||||
const BUSBDevice *Device() const;
|
||||
|
||||
// These are accessors to descriptor fields. InterfaceString() tries
|
||||
// to return a describing string of this interface. If no string is
|
||||
// available an empty string will be returned.
|
||||
uint8 Class() const;
|
||||
uint8 Subclass() const;
|
||||
uint8 Protocol() const;
|
||||
const char *InterfaceString() const;
|
||||
|
||||
const usb_interface_descriptor
|
||||
*Descriptor() const;
|
||||
|
||||
// Use OtherDescriptorAt() to get generic descriptors of an interface.
|
||||
// These are usually vendor or device specific extensions.
|
||||
status_t OtherDescriptorAt(uint32 index,
|
||||
usb_descriptor *descriptor,
|
||||
size_t length) const;
|
||||
|
||||
// CountEndpoints() and EndpointAt() can be used to iterate over the
|
||||
// available endpoints within an interface. EndpointAt() is the only
|
||||
// valid way to get BUSBEndpoint object. Note that these objects will
|
||||
// get invalid and deleted as soon as the parent interface is deleted.
|
||||
uint32 CountEndpoints() const;
|
||||
const BUSBEndpoint *EndpointAt(uint32 index) const;
|
||||
|
||||
// Using CountAlternates() you can retrieve the number of alternate
|
||||
// interfaces for this interface. Note that this interface itself
|
||||
// counts as an alternate so an alternate count of one really means
|
||||
// that you are currently using the sole interface present.
|
||||
// AlternateAt() returns the interface descriptor of the alternate
|
||||
// interface with the specified index. Using that you can peek at the
|
||||
// information contained in the descriptor without having to switch
|
||||
// to this alternate interface. Note that the alternate index set in
|
||||
// the interface descriptor returned is not necessarily the same index
|
||||
// you used to get the descriptor. Always use the zero based index you
|
||||
// used to get the information with and not the values of the returned
|
||||
// descriptor as the stack will handle that translation internally.
|
||||
// The interface descriptor returned was allocated by new and is yours.
|
||||
// You need to delete it when you're done with it.
|
||||
// With SetAlternate() you can switch this BUSBInterface object to the
|
||||
// alternate interface at the specified index. Note that all endpoints
|
||||
// retrieved through EndpointAt() will become invalid and will be
|
||||
// deleted as soon as you set an alternate interface (even if the
|
||||
// resulting interface is the same you were using before).
|
||||
uint32 CountAlternates() const;
|
||||
usb_interface_descriptor *AlternateAt(uint32 alternateIndex);
|
||||
status_t SetAlternate(uint32 alternateIndex);
|
||||
|
||||
private:
|
||||
friend class BUSBConfiguration;
|
||||
BUSBInterface(BUSBConfiguration *config,
|
||||
uint32 index, int rawFD);
|
||||
~BUSBInterface();
|
||||
|
||||
void _UpdateDescriptorAndEndpoints();
|
||||
|
||||
BUSBConfiguration *fConfiguration;
|
||||
uint32 fIndex;
|
||||
int fRawFD;
|
||||
|
||||
usb_interface_descriptor fDescriptor;
|
||||
BUSBEndpoint **fEndpoints;
|
||||
|
||||
mutable char *fInterfaceString;
|
||||
|
||||
uint32 fReserved[10];
|
||||
};
|
||||
|
||||
|
||||
/* The BUSBEndpoint represent a device endpoint that can be used to send or
|
||||
receive data. It also allows to query endpoint characteristics like
|
||||
endpoint type or direction. */
|
||||
class BUSBEndpoint {
|
||||
public:
|
||||
// Interface() returns the parent interface of this endpoint.
|
||||
// This endpoint is located at the index returned by Index() in the
|
||||
// parent interface.
|
||||
// Configuration() and Device() are convenience functions to directly
|
||||
// reach the parent configuration or device of this endpoint instead
|
||||
// of going through the parent objects.
|
||||
uint32 Index() const;
|
||||
const BUSBInterface *Interface() const;
|
||||
const BUSBConfiguration *Configuration() const;
|
||||
const BUSBDevice *Device() const;
|
||||
|
||||
// These methods can be used to check for endpoint characteristics.
|
||||
bool IsBulk() const;
|
||||
bool IsInterrupt() const;
|
||||
bool IsIsochronous() const;
|
||||
bool IsControl() const;
|
||||
|
||||
bool IsInput() const;
|
||||
bool IsOutput() const;
|
||||
|
||||
uint16 MaxPacketSize() const;
|
||||
uint8 Interval() const;
|
||||
|
||||
const usb_endpoint_descriptor
|
||||
*Descriptor() const;
|
||||
|
||||
// These methods initiate transfers to or from the endpoint. All
|
||||
// transfers are synchronous and the actually transfered amount of
|
||||
// data is returned as a result. A negative value indicates an error.
|
||||
// Which transfer type to use depends on the endpoint type.
|
||||
ssize_t ControlTransfer(uint8 requestType,
|
||||
uint8 request, uint16 value,
|
||||
uint16 index, uint16 length,
|
||||
void *data) const;
|
||||
ssize_t InterruptTransfer(void *data,
|
||||
size_t length) const;
|
||||
ssize_t BulkTransfer(void *data,
|
||||
size_t length) const;
|
||||
ssize_t IsochronousTransfer(void *data,
|
||||
size_t length,
|
||||
usb_iso_packet_descriptor *packetDescriptors,
|
||||
uint32 packetCount) const;
|
||||
|
||||
// These are convenience methods for getting and clearing the halt
|
||||
// state of an endpoint. They use the control pipe of the device to
|
||||
// send the corresponding requests.
|
||||
bool IsStalled() const;
|
||||
status_t ClearStall() const;
|
||||
private:
|
||||
friend class BUSBInterface;
|
||||
BUSBEndpoint(BUSBInterface *interface,
|
||||
uint32 index, int rawFD);
|
||||
~BUSBEndpoint();
|
||||
|
||||
BUSBInterface *fInterface;
|
||||
uint32 fIndex;
|
||||
int fRawFD;
|
||||
|
||||
usb_endpoint_descriptor fDescriptor;
|
||||
|
||||
uint32 fReserved[10];
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user