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 * 102 Descriptor() const; 103 104 // GetStringDescriptor() can be used to retrieve the raw 105 // usb_string_descriptor with a given index. The strings contained 106 // in these descriptors are usually two-byte unicode encoded. 107 size_t GetStringDescriptor(uint32 index, 108 usb_string_descriptor *descriptor, 109 size_t length) const; 110 111 // Use the DecodeStringDescriptor() convenience function to get a 112 // 0-terminated c string for a given string index. Note that this 113 // will allocate the string as "new char[];" and needs to be deleted 114 // like "delete[] string;" by the caller. 115 char * DecodeStringDescriptor(uint32 index) const; 116 117 size_t GetDescriptor(uint8 type, uint8 index, 118 uint16 languageID, void *data, 119 size_t length) const; 120 121 // With ConfigurationAt() or ActiveConfiguration() you can get an 122 // object that represents the configuration at a certain index or at 123 // the index that is currently configured. Note that the index does not 124 // necessarily correspond with the configuration value. 125 // Use the returned object as an argument to SetConfiguration() to 126 // change the active configuration of a device. 127 uint32 CountConfigurations() const; 128 const BUSBConfiguration * ConfigurationAt(uint32 index) const; 129 130 const BUSBConfiguration * ActiveConfiguration() const; 131 status_t SetConfiguration( 132 const BUSBConfiguration *configuration); 133 134 // ControlTransfer() sends requests using the default pipe 135 ssize_t ControlTransfer(uint8 requestType, 136 uint8 request, uint16 value, 137 uint16 index, uint16 length, 138 void *data) const; 139 140 private: 141 virtual void _ReservedUSBDevice1(); 142 virtual void _ReservedUSBDevice2(); 143 virtual void _ReservedUSBDevice3(); 144 virtual void _ReservedUSBDevice4(); 145 virtual void _ReservedUSBDevice5(); 146 147 char * fPath; 148 int fRawFD; 149 150 usb_device_descriptor fDescriptor; 151 BUSBConfiguration ** fConfigurations; 152 uint32 fActiveConfiguration; 153 154 mutable char * fManufacturerString; 155 mutable char * fProductString; 156 mutable char * fSerialNumberString; 157 158 uint32 fReserved[10]; 159 }; 160 161 162 /* A BUSBConfiguration object represents one of possibly multiple 163 configurations a device might have. A valid object can only be gotten 164 through the ConfigurationAt() and ActiveConfiguration() methods of a 165 BUSBDevice. 166 The BUSBConfiguration provides further access into the configuration by 167 providing CountInterfaces() and InterfaceAt() to retrieve BUSBInterface 168 objects. */ 169 class BUSBConfiguration { 170 public: 171 // Device() returns the parent device of this configuration. This 172 // configuration is located at the index returned by Index() within 173 // that parent device. 174 uint32 Index() const; 175 const BUSBDevice * Device() const; 176 177 // Gets a describing string of this configuration if available. 178 // Otherwise an empty string is returned. 179 const char * ConfigurationString() const; 180 181 const usb_configuration_descriptor * 182 Descriptor() const; 183 184 // With CountInterfaces() and InterfaceAt() you can iterate through 185 // the child interfaces of this configuration. It is the only valid 186 // way to get a BUSBInterface object. 187 // Note that the interface objects retrieved using InterfaceAt() will 188 // be invalid and deleted as soon as this configuration gets deleted. 189 uint32 CountInterfaces() const; 190 const BUSBInterface * InterfaceAt(uint32 index) const; 191 192 private: 193 friend class BUSBDevice; 194 BUSBConfiguration(BUSBDevice *device, 195 uint32 index, int rawFD); 196 ~BUSBConfiguration(); 197 198 BUSBDevice * fDevice; 199 uint32 fIndex; 200 int fRawFD; 201 202 usb_configuration_descriptor fDescriptor; 203 BUSBInterface ** fInterfaces; 204 205 mutable char * fConfigurationString; 206 207 uint32 fReserved[10]; 208 }; 209 210 211 /* The BUSBInterface class can be used to access the descriptor fields of 212 an underleying USB interface. Most importantly though it can be used to 213 iterate over and retrieve BUSBEndpoint objects that can be used to 214 transfer data over the bus. */ 215 class BUSBInterface { 216 public: 217 // Configuration() returns the parent configuration of this interface. 218 // This interface is located at the index returned by Index() in that 219 // parent configuration and represents the alternate interface returned 220 // by AlternateIndex(). 221 // Device() is a convenience function to directly reach the parent 222 // device of this interface instead of going through the configuration. 223 uint32 Index() const; 224 uint32 AlternateIndex() const; 225 const BUSBConfiguration * Configuration() const; 226 const BUSBDevice * Device() const; 227 228 // These are accessors to descriptor fields. InterfaceString() tries 229 // to return a describing string of this interface. If no string is 230 // available an empty string will be returned. 231 uint8 Class() const; 232 uint8 Subclass() const; 233 uint8 Protocol() const; 234 const char * InterfaceString() const; 235 236 const usb_interface_descriptor * 237 Descriptor() const; 238 239 // Use OtherDescriptorAt() to get generic descriptors of an interface. 240 // These are usually vendor or device specific extensions. 241 status_t OtherDescriptorAt(uint32 index, 242 usb_descriptor *descriptor, 243 size_t length) const; 244 245 // CountEndpoints() and EndpointAt() can be used to iterate over the 246 // available endpoints within an interface. EndpointAt() is the only 247 // valid way to get BUSBEndpoint object. Note that these objects will 248 // get invalid and deleted as soon as the parent interface is deleted. 249 uint32 CountEndpoints() const; 250 const BUSBEndpoint * EndpointAt(uint32 index) const; 251 252 // Using CountAlternates() you can retrieve the number of alternate 253 // interfaces for this interface. Note that this interface itself 254 // counts as an alternate so an alternate count of one really means 255 // that you are currently using the sole interface present. 256 // AlternateAt() returns the interface descriptor of the alternate 257 // interface with the specified index. Using that you can peek at the 258 // attributes of that alternate (including endpoints) without having to 259 // switch to this alternate interface. 260 // Note that you cannot use any endpoint you retrieve through an 261 // interface you get through AlternateAt(). Even if you switch to that 262 // alternate later on, you cannot use an interface returned by 263 // AlternateAt(). Instead switch to that alternate using the interface 264 // you got from the configuration and then use this switched interface 265 // to enumerate the endpoints. 266 // ActiveAlternateIndex() returns the index of the currently active 267 // alternate interface. 268 // With SetAlternate() you can switch this BUSBInterface object to the 269 // alternate interface at the specified index. Note that all endpoints 270 // retrieved through EndpointAt() will become invalid and will be 271 // deleted as soon as you set an alternate interface (even if the 272 // resulting interface is the same you were using before). 273 uint32 CountAlternates() const; 274 uint32 ActiveAlternateIndex() const; 275 const BUSBInterface * AlternateAt(uint32 alternateIndex) const; 276 status_t SetAlternate(uint32 alternateIndex); 277 278 private: 279 friend class BUSBConfiguration; 280 BUSBInterface(BUSBConfiguration *config, 281 uint32 index, uint32 alternate, 282 int rawFD); 283 ~BUSBInterface(); 284 285 void _UpdateDescriptorAndEndpoints(); 286 287 BUSBConfiguration * fConfiguration; 288 uint32 fIndex; 289 uint32 fAlternate; 290 int fRawFD; 291 292 usb_interface_descriptor fDescriptor; 293 BUSBEndpoint ** fEndpoints; 294 295 mutable uint32 fAlternateCount; 296 mutable BUSBInterface ** fAlternates; 297 298 mutable char * fInterfaceString; 299 300 uint32 fReserved[10]; 301 }; 302 303 304 /* The BUSBEndpoint represent a device endpoint that can be used to send or 305 receive data. It also allows to query endpoint characteristics like 306 endpoint type or direction. */ 307 class BUSBEndpoint { 308 public: 309 // Interface() returns the parent interface of this endpoint. 310 // This endpoint is located at the index returned by Index() in the 311 // parent interface. 312 // Configuration() and Device() are convenience functions to directly 313 // reach the parent configuration or device of this endpoint instead 314 // of going through the parent objects. 315 uint32 Index() const; 316 const BUSBInterface * Interface() const; 317 const BUSBConfiguration * Configuration() const; 318 const BUSBDevice * Device() const; 319 320 // These methods can be used to check for endpoint characteristics. 321 bool IsBulk() const; 322 bool IsInterrupt() const; 323 bool IsIsochronous() const; 324 bool IsControl() const; 325 326 bool IsInput() const; 327 bool IsOutput() const; 328 329 uint16 MaxPacketSize() const; 330 uint8 Interval() const; 331 332 const usb_endpoint_descriptor * 333 Descriptor() const; 334 335 // These methods initiate transfers to or from the endpoint. All 336 // transfers are synchronous and the actually transfered amount of 337 // data is returned as a result. A negative value indicates an error. 338 // Which transfer type to use depends on the endpoint type. 339 ssize_t ControlTransfer(uint8 requestType, 340 uint8 request, uint16 value, 341 uint16 index, uint16 length, 342 void *data) const; 343 ssize_t InterruptTransfer(void *data, 344 size_t length) const; 345 ssize_t BulkTransfer(void *data, 346 size_t length) const; 347 ssize_t IsochronousTransfer(void *data, 348 size_t length, 349 usb_iso_packet_descriptor *packetDescriptors, 350 uint32 packetCount) const; 351 352 // These are convenience methods for getting and clearing the halt 353 // state of an endpoint. They use the control pipe of the device to 354 // send the corresponding requests. 355 bool IsStalled() const; 356 status_t ClearStall() const; 357 358 private: 359 friend class BUSBInterface; 360 BUSBEndpoint(BUSBInterface *interface, 361 uint32 index, int rawFD); 362 ~BUSBEndpoint(); 363 364 BUSBInterface * fInterface; 365 uint32 fIndex; 366 int fRawFD; 367 368 usb_endpoint_descriptor fDescriptor; 369 370 uint32 fReserved[10]; 371 }; 372 373 #endif 374