diff options
author | pancake <pancake@dazo> | 2007-06-12 15:29:07 +0200 |
---|---|---|
committer | pancake <pancake@dazo> | 2007-06-12 15:29:07 +0200 |
commit | ea97ac427eb9ff7ec48baf3a5ab7cc293fc34b70 (patch) | |
tree | 271288556a4a431a25746e5da596feb3dd580d64 /libusb/usbpp.h | |
parent | a3af55acb4141cd0d23f53b2ec0c5c1d2434aa22 (diff) | |
download | 0xFFFF-ea97ac427eb9ff7ec48baf3a5ab7cc293fc34b70.tar.bz2 |
* Initial import of the libusb source tree into the flasher - optional, but useful for embedding - avoids gnu autosux problems
Diffstat (limited to 'libusb/usbpp.h')
-rw-r--r-- | libusb/usbpp.h | 855 |
1 files changed, 855 insertions, 0 deletions
diff --git a/libusb/usbpp.h b/libusb/usbpp.h new file mode 100644 index 0000000..abda64f --- /dev/null +++ b/libusb/usbpp.h @@ -0,0 +1,855 @@ +// -*- C++;indent-tabs-mode: t; tab-width: 4; c-basic-offset: 4; -*- +#ifndef __USBPP_HEADER__ +#define __USBPP_HEADER__ + +#include <string> +#include <list> + +#include <usb.h> + +/* + * The following usb.h function is not wrapped yet: + * char *usb_strerror(void); + */ + + +/** + * \brief Classes to access Universal Serial Bus devices + * + * The USB Namespace provides a number of classes to work + * with Universal Serial Bus (USB) devices attached to the + * system. + * + * \author Brad Hards + */ +namespace USB { + + class Device; + + /** + * \brief Class representing a device endpoint + * + * This class represents a device endpoint. You need this class to + * perform bulk reads and writes. + * + */ + class Endpoint { + /** + * Busses is a friend because it fills in the descriptor type + * information on initialisation and rescan. + */ + friend class Busses; + public: + Endpoint() {}; + +#ifdef USE_UNTESTED_LIBUSBPP_METHODS + /** + * \brief Bulk write + * + * This method performs a bulk transfer to the endpoint. + * + * \param message is the message to be sent. + * \param timeout is the USB transaction timeout in milliseconds + * + * \returns the number of bytes sent, or a negative value on + * failure + */ + int bulkWrite(QByteArray message, int timeout = 100); + + /** + * \brief Bulk read + * + * This method performs a bulk transfer from the endpoint. + * + * \param length is the maximum data transfer required. + * \param message is the message that was received. + * \param timeout is the USB transaction timeout in milliseconds + * + * \returns the number of bytes received, or a negative value on + * failure + */ + int bulkRead(int length, unsigned char *message, int timeout = 100); + + /** + * \brief Reset endpoint + * + * This method resets the endpoint. + */ + int reset(void); + + /** + * \brief Clear halt + * + * This method clears a halt (stall) on the endpoint. + */ + int clearHalt(void); + +#endif /* USE_UNTESTED_LIBUSBPP_METHODS */ + + /** + * \brief Endpoint descriptor information output + * + * This method dumps out the various characteristics + * of the endpoint to standard output. + * + * It is mostly useful for debugging. + */ + void dumpDescriptor(void); + + private: + void setDescriptor(struct usb_endpoint_descriptor); + void setParent(Device *parent); + u_int8_t m_Length; + u_int8_t m_DescriptorType; + u_int8_t m_EndpointAddress; + u_int8_t m_Attributes; + u_int16_t m_MaxPacketSize; + u_int8_t m_Interval; + u_int8_t m_Refresh; + u_int8_t m_SynchAddress; + Device *m_parent; + }; + + class AltSetting : public std::list<Endpoint *> { + /** + * Busses is a friend because it fills in the descriptor type + * information on initialisation and rescan. + */ + friend class Busses; + public: + AltSetting() {}; + u_int8_t numEndpoints(void); + + /** + * \brief AltSetting descriptor information output + * + * This method dumps out the various characteristics + * of the alternate setting to standard output. + * + * It is mostly useful for debugging. + */ + void dumpDescriptor(void); + + Endpoint *firstEndpoint(void); + Endpoint *nextEndpoint(void); + Endpoint *lastEndpoint(void); + + private: + std::list<Endpoint *>::const_iterator iter; + + void setDescriptor(struct usb_interface_descriptor); + /* we don't use a normal usb_interface_descriptor */ + /* because that would bring in the endpoint list */ + u_int8_t m_Length; + u_int8_t m_DescriptorType; + u_int8_t m_InterfaceNumber; + u_int8_t m_AlternateSetting; + u_int8_t m_NumEndpoints; + u_int8_t m_InterfaceClass; + u_int8_t m_InterfaceSubClass; + u_int8_t m_InterfaceProtocol; + u_int8_t m_Interface; + }; + + /** + * \brief Class representing an interface of a Device + * + * The Interface class represents a USB interface + * for a device attached to a Universal Serial Bus. + * + * Interfaces are the main element of the USB class + * structure. + * + * \author Brad Hards + */ + class Interface : public std::list<AltSetting *> { + /** + * Busses is a friend because it fills in the descriptor type + * information on initialisation and rescan. + */ + friend class Busses; + public: + Interface() {}; + +#ifdef LIBUSB_HAS_GET_DRIVER_NP + /** + * \brief get the current driver for an interface + * + * \param driver a string containing the name of the current + * driver for the interface. You can typically pass in an empty + * string for this. + * + * \return length of string, or 0 on error. + */ + int driverName(std::string &driver); +#endif + +#ifdef USE_UNTESTED_LIBUSBPP_METHODS + /** + * \brief Claim this interface + * + * This method claims the interface. You have to claim the + * interface before performing any operations on the interface (or + * on endpoints that are part of the interface). + * + * \return 0 on success or negative number on error. + */ + int claim(void); + + /** + * \brief Release this interface + * + * This method releases the interface. You should release the + * interface after all operations on it (and any lower level + * endpoints) are completed. + * + * \return 0 on success or negative number on error. + */ + int release(void); + + /** + * \brief Set interface alternate setting + * + * This method sets the interface to a particular AltSetting. + * + * \param altSettingNumber the AltSetting that the interface + * should be changed to. + * + * \return 0 on success, or a negative number in case of error. + */ + int setAltSetting(int altSettingNumber); +#endif /* USE_UNTESTED_LIBUSBPP_METHODS */ + + /** + * \brief Number of Alternative Settings that this interface has + * + * This is a simple accessor method that specifies the number + * alternative settings that this device interface has. + */ + u_int8_t numAltSettings(void); + + /** + * \brief First AltSetting for the Interface + * + * This method returns a pointer to the first AltSetting + * for the Interface. + * + * See nextAltSetting() for an example of how it might be + * used. + * + * \see nextAltSetting(), lastAltSetting(), numAltSettings() + */ + AltSetting *firstAltSetting(void); + + /** + * \brief Next AltSetting for the Interface + * + * This method returns a pointer to the next AltSetting + * for the Interface. + * + * If you want to iterate through each AltSetting on + * a device, you can use something like the following: + * \code + * USB::Configuration *this_Configuration; + * this_Configuration = device->firstConfiguration(); + * for (i=0; i < device->numConfigurations(); i++) { + * this_Configuration->dumpDescriptor(); + * USB::Interface *this_Interface; + * this_Interface = this_Configuration->firstInterface(); + * for (j=0; j < this_Configuration->numInterfaces(); j++) { + * USB::AltSetting *this_AltSetting; + * this_AltSetting = this_Interface->firstAltSetting(); + * for (k=0; k < this_Interface->numAltSettings(); k++) { + * // do something with this_AltSetting + * this_AltSetting = this_Interface->nextAltSetting(); + * } + * this_Interface = this_Configuration->nextInterface(); + * } + * this_Configuration = device->nextConfiguration(); + * } + * \endcode + * + * \see firstAltSetting(), lastAltSetting(), numAltSettings() + */ + AltSetting *nextAltSetting(void); + + /** + * \brief Last AltSetting for the Interface + * + * This method returns a pointer to the last AltSetting + * for the Interface. + * + * \see firstAltSetting(), nextAltSetting(), numAltSettings() + */ + + AltSetting *lastAltSetting(void); + + private: + std::list<AltSetting *>::const_iterator iter; + + void setNumAltSettings(u_int8_t); + void setParent(Device *parent); + u_int8_t m_numAltSettings; + Device *m_parent; + + /* index representing the interface, in this configuration */ + int m_interfaceNumber; + void setInterfaceNumber(int interfaceNumber); + }; + + /** + * \brief Class representing a configuration of a Device + * + * The Configuration class represents a single configuration + * of a device attached to a Universal Serial Bus. + * + * \author Brad Hards + */ + class Configuration : public std::list<Interface *> { + /** + * Busses is a friend because it fills in the descriptor type + * information on initialisation and rescan. + */ + friend class Busses; + public: + Configuration() {}; + + /** + * \brief Configuration descriptor information output + * + * This method dumps out the various characteristics + * of the configuration to standard output. + * + * It is mostly useful for debugging. + */ + void dumpDescriptor(void); + + /** + * \brief Number of Interfaces that this device has + * + * This is a simple accessor method that specifies the number + * Interfaces that this device configuration has. + */ + u_int8_t numInterfaces(void); + + /** + * \brief First Interface for the Configuration + * + * This method returns a pointer to the first Interface + * for the Configuration. + * + * See nextInterface() for an example of how it might be + * used. + * + * \see nextInterface(), lastInterface(), numInterfaces() + */ + Interface *firstInterface(void); + + /** + * \brief Next Interface for the Configuration + * + * This method returns a pointer to the next Interface + * for the Configuration. + * + * If you want to iterate through each Interface on + * a device, you can use something like the following: + * \code + * USB::Configuration *this_Configuration; + * this_Configuration = device->firstConfiguration(); + * for (i=0; i < device->numConfigurations(); i++) { + * this_Interface = this_Configuration->firstInterface(); + * for (j=0; j < this_Configuration->numInterfaces(); j++) { + * // do something with this_Interface + * this_Interface = this_Configuration->nextInterface(); + * } + * this_Configuration->nextConfiguration(); + * } + * \endcode + * + * \see firstInterface(), lastInterface(), numInterfaces() + */ + Interface *nextInterface(void); + + /** + * \brief Last Interface for the Configuration + * + * This method returns a pointer to the last Interface + * for the Configuration. + * + * \see firstInterface(), nextInterface(), numInterfaces() + */ + Interface *lastInterface(void); + + private: + std::list<Interface *>::const_iterator iter; + + void setDescriptor(struct usb_config_descriptor); + /* we don't use a normal usb_config_descriptor */ + /* because that would bring in the interface list */ + u_int8_t m_Length; + u_int8_t m_DescriptorType; + u_int16_t m_TotalLength; + u_int8_t m_NumInterfaces; + u_int8_t m_ConfigurationValue; + u_int8_t m_Configuration; + u_int8_t m_Attributes; + u_int8_t m_MaxPower; + }; + + /** + * \brief Class representing a Device on the Bus + * + * The Device class represents a single device + * attached to a Universal Serial Bus. + * + * \author Brad Hards + */ + class Device : public std::list<Configuration *> { + /** + * Busses is a friend because it fills in the descriptor type + * information on initialisation and rescan. + */ + friend class Busses; + /** + * Interface is a friend because it needs the handle() function to + * perform claim(), release(). + */ + friend class Interface; + /** + * Endpoint is a friend because it needs the handle() function to + * perform reads, writes, and other transactions. + */ + friend class Endpoint; + + public: + Device() {}; + ~Device(); + + /** + * \brief OS representation of filename for this device + * + * libusb++ provides a uniform way of accessing USB + * devices irrespective of the underlying Operation System + * representation. If you want to map the libusb++ representation + * to the Operating System representation, you can do this + * with filename(). + * + * On Linux, the filename is usually something like 002, which + * represents the second device (usually the first real device, + * after the root hub pseudo-device) on the bus. + * + * \see Bus::directoryName() + */ + std::string fileName(void); + + /** + * \brief The vendor ID number, as provided by the device. + * + * This method returns a number containing the vendor + * (manufacturer) identification number. These are allocated + * by the USB Implementers Forum, and you can construct a + * lookup based on the number to get the manufacturer's name, + * even if the device does not contain a vendor string. + * + * \see Vendor() + */ + u_int16_t idVendor(void); + + /** + * \brief The product ID number, as provided by the device. + * + * This method returns a number containing the product + * identification number. These are allocated + * by the manufacturer, and should be different on each device. + * + * \see Product() + */ + u_int16_t idProduct(void); + + /** + * \brief The product's revision ID, as provided by the device. + * + * This method returns a number containing the product's revision. + * This revision level is nominally binary coded decimal, but + * hexadecimal revision levels are not uncommon. The binary coded + * decimal version nominally has a major version in the high byte, + * and a minor version in the low byte. + */ + u_int16_t idRevision(void); + + /** + * \brief The device's USB class, as provided by the device. + * + * This method returns a number containing the device's class. + * These are defined by the USB Implementer's Forum. + * + * A code of Zero is special (and common) - it means that the + * class is found in the Interface descriptor, rather than in the + * Device descriptor. + * + * A code of 0xFF is also special (and far too common) - it means + * that the manufacturer didn't conform to one of the defined + * class specifications, and chose to implement a vendor specified + * protocol. + * + */ + u_int8_t devClass(void); + + /** + * \brief The device's USB subclass, as provided by the device. + * + * This method returns a number containing the device's subclass. + * These subclasses are defined by the USB Implementer's Forum, + * and only have meaning in the context of a specified class. + */ + u_int8_t devSubClass(void); + + /** + * \brief The device's USB protocol, as provided by the device. + * + * This method returns a number containing the device's protocol. + * These protocols are defined by the USB Implementer's Forum, and + * only have meaning in the context of a specified class and + * subclass. + */ + u_int8_t devProtocol(void); + + + /** + * \brief The vendor name string, as provided by the device. + * + * This method returns a string containing the name of the + * device's vendor (manufacturer), as encoded into the device. + * + * Note that not all devices contain a vendor name, and also + * that under some operating systems you may not be able to + * read the vendor name without elevated privledges (typically + * root privledges). + * + * \see idVendor() + **/ + std::string Vendor(void); + + /** + * \brief The product name string, as provided by the device. + * + * This method returns a string containing the name of the + * device's product name, as encoded into the device. + * + * Note that not all devices contain a product name, and also + * that under some operating systems you may not be able to + * read the vendor name without elevated privledges (typically + * root privledges). + * + * \see idProduct() + **/ + std::string Product(void); + + /** + * \brief The serial number string, as provided by the device. + * + * This method returns a string containing a serial number for + * the device, as encoded into the device. + * + * Note that few devices contain a serial number string, and also + * that under some operating systems you may not be able to + * read the serial number without elevated privledges (typically + * root privledges). The USB specification requires that serial + * numbers are unique if they are provided, but adherence to this + * requirement by manufacturers is not universal. + **/ + std::string SerialNumber(void); + + /** + * \brief Number of Configurations that this device has + * + * This is a simple accessor method that specifies the number + * configurations that this device has. + */ + u_int8_t numConfigurations(void); + + /** + * \brief fetch an arbitrary string from the device + * + * \param string the string from the device. You can typically + * pass in an empty string for this. + * \param index the index of the string required + * \param lang the language ID to use. Defaults to using the + * first language ID. + * + * \return length of string, or 0 on error. + */ + int string(std::string &buf, int index, u_int16_t lang=0); + + /** + * \brief First Configuration for the Device + * + * This method returns a pointer to the first Configuration + * for the Device. + * + * See nextConfiguration() for an example of how it might be + * used. + */ + Configuration *firstConfiguration(void); + + /** + * \brief Next Configuration for the Device + * + * This method returns a pointer to the next Configuration + * for the Device. + * + * If you want to iterate through each Configuration on + * a device, you can use something like the following: + * \code + * USB::Configuration *this_Configuration; + * this_Configuration = device->firstConfiguration(); + * for (i=0; i < device->numConfigurations(); i++) { + * // do something with this_Configuration + * this_Configuration->nextConfiguration(); + * } + * \endcode + */ + Configuration *nextConfiguration(void); + + /** + * \brief Last Configuration for the Device + * + * This method returns a pointer to the last Configuration + * for the Device. + * + */ + Configuration *lastConfiguration(void); + + /** + * \brief USB control transfer + * + * This method performs a standard control transfer to the default + * endpoint. See the USB specification for more details on this. + * + * \param requestType corresponds to the bmRequestType field + * in the transfer + * \param request corresponds to the bRequest field in the + * transfer + * \param value corresponds to the wValue field in the transfer + * \param index corresponds to the wIndex field in the transfer + * \param length corresponds to the wLength field in the transfer + * \param payload corresponds to the data phase of a control + * transfer + * \param timeout is the timeout period for the control transfer, + * in milliseconds + * + * \return number of bytes sent or received, or a negative number + * in case of error. + */ + int controlTransfer(u_int8_t requestType, u_int8_t request, + u_int16_t value, u_int16_t index, u_int16_t length, + unsigned char *payload, + int timeout = 100); + +#ifdef USE_UNTESTED_LIBUSBPP_METHODS + /** + * \brief USB device reset + * + * This method performs a device reset - see USB Specification + * 9.1 for how this changes the device state to the Default state. + * + * \return 0 on success, or a negative number in case of error. + */ + int reset(void); + + /** + * \brief Set device configuration + * + * This method sets the device to a particular Configuration. + * + * \param configurationNumber the configuration that the device + * should be changed to. + * + * \return 0 on success, or a negative number in case of error. + */ + int setConfiguration(int configurationNumber); +#endif /* USE_UNTESTED_LIBUSBPP_METHODS */ + + private: + std::list<Configuration *>::const_iterator iter; + + struct usb_dev_handle *handle(); + void setFileName(std::string); + void setDescriptor(struct usb_device_descriptor); + void setVendor(std::string); + void setProduct(std::string); + void setSerialNumber(std::string); + void setDevHandle(struct usb_dev_handle *); + std::string m_fileName; + std::string m_Vendor; + std::string m_Product; + std::string m_SerialNumber; + struct usb_device *m_dev; + struct usb_dev_handle *m_handle; + struct usb_device_descriptor m_descriptor; + }; + + /** + * \brief Class representing a single bus on the machine + * + * This class is essentially a list of Device class instances + */ + class Bus : public std::list<Device *> { + /** + * Busses is a friend because it fills in the directory name + * information on initialisation and rescan. + */ + friend class Busses; + public: + Bus() {}; + /** + * \brief OS representation of directory name for this Bus + * + * libusb++ provides a uniform way of accessing USB + * busses irrespective of the underlying Operation System + * representation. If you want to map the libusb++ representation + * to the Operating System representation, you can do this + * with directory name(). + * + * On Linux, the directoryname is usually something like 003, which + * represents the third bus on the host. + * + * \see Directory::filename() + */ + std::string directoryName(void); + private: + std::list<Device *>::const_iterator iter; + + void setDirectoryName(std::string); + std::string m_directoryName; + }; + + /** + * \brief A vendor/product ID pair + * + * DeviceID provides a list of (vendor, product) identification + * pairs. It is intended for use in a list of device numbers to + * search for, but there is no reason why it couldn't be used for a + * general purpose (vendor,product) tuple if you had some reason for + * this. + * + * The description for Busses::match() provides an example of how + * this class might be used. + * + * \see DeviceIDList, Busses::match() + */ + class DeviceID { + public: + DeviceID() {}; + /** + * \brief Standard constructor + * + * This constructor takes (vendor, product) tuple, which are + * stored away. + * + * \param vendor the 16 bit vendor number for the device + * \param product the 16 bit product number for the device + */ + DeviceID(u_int16_t vendor, u_int16_t product); + + /** + * \brief vendor number for the device + * + * This method returns the 16 bit vendor number. + */ + u_int16_t vendor(void); + + /** + * \brief product number for the device + * + * This method returns the 16 bit product number. + */ + u_int16_t product(void); + + private: + u_int16_t m_vendor; + u_int16_t m_product; + }; + + /** + * \brief A list of vendor/product pairs + * + * DeviceIDList provides a list of DeviceID classes, which is + * essentially a list of (vendor, product) identification pairs. + * + * \see DeviceID + */ + typedef std::list<DeviceID> DeviceIDList; + + /** + * \brief Class representing all the busses on the machine + * + * This class is essentially a list of Bus class instances + */ + class Busses : public std::list<Bus *> { + public: + Busses(); + + /** + * \brief Update method + * + * This method can be called to rescan the various devices + * attached to the various busses. You should use it to + * update if things change. Unfortunately there is no + * way to automatically detect this change in a portable way, + * so worst case is that you need to call this using some + * kind of timer in the background. + */ + void rescan(void); + + /** + * \brief find all devices with matching device class designator + * + * This method searches every device on every bus, and returns a + * list of pointers to the devices that have a matching device + * class code + */ + std::list<Device *> match(u_int8_t Class); + + /** + * \brief find all devices with matching device IDs + * + * This method searches every device on every bus, and returns a + * list of pointers to the devices that have a matching device + * ID. That is, if the (vendor, product) tuple of a device matches + * one of the tuples on the list, then the device will be added to + * the list of matches. + * + * An example of usage is shown below: + * \code + * USB::Busses buslist; + * USB::Device *device; + * std::list<USB::Device> miceFound; + * USB::DeviceIDList mouseList; + * + * mouseList.append(USB::DeviceID(VENDOR_LOGITECH, 0xC00E)); // Wheel Mouse Optical + * mouseList.append(USB::DeviceID(VENDOR_LOGITECH, 0xC012)); // MouseMan Dual Optical + * mouseList.append(USB::DeviceID(VENDOR_LOGITECH, 0xC506)); // MX700 Optical Mouse + * + * miceFound = buslist.match(mouseList); + * + * for ( device = miceFound.first(); device; device = miceFound.next() ) { + * // do something with each mouse that matched + * } + * FIXME: This is incorrect now + * \endcode + */ + std::list<Device *> match(DeviceIDList); + + private: + std::list<Bus *>::const_iterator iter; + }; + + class Error { + public: + private: + }; + +} +#endif /* __USBPP_HEADER__ */ + |