1 /* 2 * Copyright 2007-2008, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #ifndef _USBKIT_H 7 #define _USBKIT_H 8 9 #include <SupportDefs.h> 10 #include <USB3.h> 11 #include <USB_spec.h> 12 13 14 class BUSBRoster; 15 class BUSBDevice; 16 class BUSBConfiguration; 17 class BUSBInterface; 18 class BUSBEndpoint; 19 20 21 /* The BUSBRoster class can be used to watch for devices that get attached or 22 removed from the USB bus. 23 You subclass the roster and implement the pure virtual DeviceAdded() and 24 DeviceRemoved() hooks. */ 25 class BUSBRoster { 26 public: 27 BUSBRoster(); 28 virtual ~BUSBRoster(); 29 30 // The DeviceAdded() hook will be called when a new device gets 31 // attached to the USB bus. The hook is called with an initialized 32 // BUSBDevice object. If you return B_OK from your hook the object 33 // will stay valid and the DeviceRemoved() hook will be called with 34 // for it. Otherwise the object is deleted and DeviceRemoved() 35 // is not called. 36 virtual status_t DeviceAdded(BUSBDevice *device) = 0; 37 38 // When a device gets detached from the bus that you hold a 39 // BUSBDevice object for (gotten through DeviceAdded()) the 40 // DeviceRemoved() hook will be called. The device object gets 41 // invalid and will be deleted as soon as you return from the hook 42 // so be sure to remove all references to it. 43 virtual void DeviceRemoved(BUSBDevice *device) = 0; 44 45 void Start(); 46 void Stop(); 47 48 private: 49 virtual void _ReservedUSBRoster1(); 50 virtual void _ReservedUSBRoster2(); 51 virtual void _ReservedUSBRoster3(); 52 virtual void _ReservedUSBRoster4(); 53 virtual void _ReservedUSBRoster5(); 54 55 void *fLooper; 56 uint32 fReserved[10]; 57 }; 58 59 60 /* The BUSBDevice presents an interface to USB device. You can either get 61 it through the BUSBRoster or by creating one yourself and setting it to 62 a valid raw usb device (with a path of "/dev/bus/usb/x"). 63 The device class provides direct accessors for descriptor fields as well 64 as convenience functions to directly get string representations of fields. 65 The BUSBDevice also provides access for the BUSBConfiguration objects of 66 a device. These objects and all of their child objects depend on the 67 parent device and will be deleted as soon as the device object is 68 destroyed */ 69 class BUSBDevice { 70 public: 71 BUSBDevice(const char *path = NULL); 72 virtual ~BUSBDevice(); 73 74 virtual status_t InitCheck(); 75 76 status_t SetTo(const char *path); 77 void Unset(); 78 79 // Returns the location on the bus represented as hub/device sequence 80 const char *Location() const; 81 bool IsHub() const; 82 83 // These are direct accessors to descriptor fields 84 uint16 USBVersion() const; 85 uint8 Class() const; 86 uint8 Subclass() const; 87 uint8 Protocol() const; 88 uint8 MaxEndpoint0PacketSize() const; 89 uint16 VendorID() const; 90 uint16 ProductID() const; 91 uint16 Version() const; 92 93 // The string functions return the string representation of the 94 // descriptor data. The strings are decoded to normal 0 terminated 95 // c strings and are cached and owned by the object. 96 // If a string is not available an empty string is returned. 97 const char *ManufacturerString() const; 98 const char *ProductString() const; 99 const char *SerialNumberString() const; 100 101 const usb_device_descriptor *Descriptor() const; 102 103 // GetStringDescriptor() can be used to retrieve the raw 104 // usb_string_descriptor with a given index. The strings contained 105 // in these descriptors are usually two-byte unicode encoded. 106 size_t GetStringDescriptor(uint32 index, 107 usb_string_descriptor *descriptor, 108 size_t length) const; 109 110 // Use the DecodeStringDescriptor() convenience function to get a 111 // 0-terminated c string for a given string index. Note that this 112 // will allocate the string as "new char[];" and needs to be deleted 113 // like "delete[] string;" by the caller. 114 char *DecodeStringDescriptor(uint32 index) const; 115 116 size_t GetDescriptor(uint8 type, uint8 index, 117 uint16 languageID, void *data, 118 size_t length) const; 119 120 // With ConfigurationAt() or ActiveConfiguration() you can get an 121 // object that represents the configuration at a certain index or at 122 // the index that is currently configured. Note that the index does not 123 // necessarily correspond with the configuration value. 124 // Use the returned object as an argument to SetConfiguration() to 125 // change the active configuration of a device. 126 uint32 CountConfigurations() const; 127 const BUSBConfiguration *ConfigurationAt(uint32 index) const; 128 129 const BUSBConfiguration *ActiveConfiguration() const; 130 status_t SetConfiguration( 131 const BUSBConfiguration *configuration); 132 133 // ControlTransfer() sends requests using the default pipe 134 ssize_t ControlTransfer(uint8 requestType, 135 uint8 request, uint16 value, 136 uint16 index, uint16 length, 137 void *data) const; 138 139 private: 140 virtual void _ReservedUSBDevice1(); 141 virtual void _ReservedUSBDevice2(); 142 virtual void _ReservedUSBDevice3(); 143 virtual void _ReservedUSBDevice4(); 144 virtual void _ReservedUSBDevice5(); 145 146 char *fPath; 147 int fRawFD; 148 149 usb_device_descriptor fDescriptor; 150 BUSBConfiguration **fConfigurations; 151 uint32 fActiveConfiguration; 152 153 mutable char *fManufacturerString; 154 mutable char *fProductString; 155 mutable char *fSerialNumberString; 156 157 uint32 fReserved[10]; 158 }; 159 160 161 /* A BUSBConfiguration object represents one of possibly multiple 162 configurations a device might have. A valid object can only be gotten 163 through the ConfigurationAt() and ActiveConfiguration() methods of a 164 BUSBDevice. 165 The BUSBConfiguration provides further access into the configuration by 166 providing CountInterfaces() and InterfaceAt() to retrieve BUSBInterface 167 objects. */ 168 class BUSBConfiguration { 169 public: 170 // Device() returns the parent device of this configuration. This 171 // configuration is located at the index returned by Index() within 172 // that parent device. 173 uint32 Index() const; 174 const BUSBDevice *Device() const; 175 176 // Gets a describing string of this configuration if available. 177 // Otherwise an empty string is returned. 178 const char *ConfigurationString() const; 179 180 const usb_configuration_descriptor 181 *Descriptor() const; 182 183 // With CountInterfaces() and InterfaceAt() you can iterate through 184 // the child interfaces of this configuration. It is the only valid 185 // way to get a BUSBInterface object. 186 // Note that the interface objects retrieved using InterfaceAt() will 187 // be invalid and deleted as soon as this configuration gets deleted. 188 uint32 CountInterfaces() const; 189 const BUSBInterface *InterfaceAt(uint32 index) const; 190 191 private: 192 friend class BUSBDevice; 193 BUSBConfiguration(BUSBDevice *device, 194 uint32 index, int rawFD); 195 ~BUSBConfiguration(); 196 197 BUSBDevice *fDevice; 198 uint32 fIndex; 199 int fRawFD; 200 201 usb_configuration_descriptor fDescriptor; 202 BUSBInterface **fInterfaces; 203 204 mutable char *fConfigurationString; 205 206 uint32 fReserved[10]; 207 }; 208 209 210 /* The BUSBInterface class can be used to access the descriptor fields of 211 an underleying USB interface. Most importantly though it can be used to 212 iterate over and retrieve BUSBEndpoint objects that can be used to 213 transfer data over the bus. */ 214 class BUSBInterface { 215 public: 216 // Configuration() returns the parent configuration of this interface. 217 // This interface is located at the index returned by Index() in that 218 // parent configuration. 219 // Device() is a convenience function to directly reach the parent 220 // device of this interface instead of going through the configuration. 221 uint32 Index() const; 222 const BUSBConfiguration *Configuration() const; 223 const BUSBDevice *Device() const; 224 225 // These are accessors to descriptor fields. InterfaceString() tries 226 // to return a describing string of this interface. If no string is 227 // available an empty string will be returned. 228 uint8 Class() const; 229 uint8 Subclass() const; 230 uint8 Protocol() const; 231 const char *InterfaceString() const; 232 233 const usb_interface_descriptor 234 *Descriptor() const; 235 236 // Use OtherDescriptorAt() to get generic descriptors of an interface. 237 // These are usually vendor or device specific extensions. 238 status_t OtherDescriptorAt(uint32 index, 239 usb_descriptor *descriptor, 240 size_t length) const; 241 242 // CountEndpoints() and EndpointAt() can be used to iterate over the 243 // available endpoints within an interface. EndpointAt() is the only 244 // valid way to get BUSBEndpoint object. Note that these objects will 245 // get invalid and deleted as soon as the parent interface is deleted. 246 uint32 CountEndpoints() const; 247 const BUSBEndpoint *EndpointAt(uint32 index) const; 248 249 // Using CountAlternates() you can retrieve the number of alternate 250 // interfaces for this interface. Note that this interface itself 251 // counts as an alternate so an alternate count of one really means 252 // that you are currently using the sole interface present. 253 // AlternateAt() returns the interface descriptor of the alternate 254 // interface with the specified index. Using that you can peek at the 255 // information contained in the descriptor without having to switch 256 // to this alternate interface. Note that the alternate index set in 257 // the interface descriptor returned is not necessarily the same index 258 // you used to get the descriptor. Always use the zero based index you 259 // used to get the information with and not the values of the returned 260 // descriptor as the stack will handle that translation internally. 261 // The interface descriptor returned was allocated by new and is yours. 262 // You need to delete it when you're done with it. 263 // With SetAlternate() you can switch this BUSBInterface object to the 264 // alternate interface at the specified index. Note that all endpoints 265 // retrieved through EndpointAt() will become invalid and will be 266 // deleted as soon as you set an alternate interface (even if the 267 // resulting interface is the same you were using before). 268 uint32 CountAlternates() const; 269 usb_interface_descriptor *AlternateAt(uint32 alternateIndex); 270 status_t SetAlternate(uint32 alternateIndex); 271 272 private: 273 friend class BUSBConfiguration; 274 BUSBInterface(BUSBConfiguration *config, 275 uint32 index, int rawFD); 276 ~BUSBInterface(); 277 278 void _UpdateDescriptorAndEndpoints(); 279 280 BUSBConfiguration *fConfiguration; 281 uint32 fIndex; 282 int fRawFD; 283 284 usb_interface_descriptor fDescriptor; 285 BUSBEndpoint **fEndpoints; 286 287 mutable char *fInterfaceString; 288 289 uint32 fReserved[10]; 290 }; 291 292 293 /* The BUSBEndpoint represent a device endpoint that can be used to send or 294 receive data. It also allows to query endpoint characteristics like 295 endpoint type or direction. */ 296 class BUSBEndpoint { 297 public: 298 // Interface() returns the parent interface of this endpoint. 299 // This endpoint is located at the index returned by Index() in the 300 // parent interface. 301 // Configuration() and Device() are convenience functions to directly 302 // reach the parent configuration or device of this endpoint instead 303 // of going through the parent objects. 304 uint32 Index() const; 305 const BUSBInterface *Interface() const; 306 const BUSBConfiguration *Configuration() const; 307 const BUSBDevice *Device() const; 308 309 // These methods can be used to check for endpoint characteristics. 310 bool IsBulk() const; 311 bool IsInterrupt() const; 312 bool IsIsochronous() const; 313 bool IsControl() const; 314 315 bool IsInput() const; 316 bool IsOutput() const; 317 318 uint16 MaxPacketSize() const; 319 uint8 Interval() const; 320 321 const usb_endpoint_descriptor 322 *Descriptor() const; 323 324 // These methods initiate transfers to or from the endpoint. All 325 // transfers are synchronous and the actually transfered amount of 326 // data is returned as a result. A negative value indicates an error. 327 // Which transfer type to use depends on the endpoint type. 328 ssize_t ControlTransfer(uint8 requestType, 329 uint8 request, uint16 value, 330 uint16 index, uint16 length, 331 void *data) const; 332 ssize_t InterruptTransfer(void *data, 333 size_t length) const; 334 ssize_t BulkTransfer(void *data, 335 size_t length) const; 336 ssize_t IsochronousTransfer(void *data, 337 size_t length, 338 usb_iso_packet_descriptor *packetDescriptors, 339 uint32 packetCount) const; 340 341 // These are convenience methods for getting and clearing the halt 342 // state of an endpoint. They use the control pipe of the device to 343 // send the corresponding requests. 344 bool IsStalled() const; 345 status_t ClearStall() const; 346 private: 347 friend class BUSBInterface; 348 BUSBEndpoint(BUSBInterface *interface, 349 uint32 index, int rawFD); 350 ~BUSBEndpoint(); 351 352 BUSBInterface *fInterface; 353 uint32 fIndex; 354 int fRawFD; 355 356 usb_endpoint_descriptor fDescriptor; 357 358 uint32 fReserved[10]; 359 }; 360 361 #endif 362