2 * Copyright 2007-2008, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Michael Lotz <mmlr@mlotz.ch>
17 BUSBDevice::BUSBDevice(const char *path
)
20 fConfigurations(NULL
),
21 fActiveConfiguration(0),
22 fManufacturerString(NULL
),
24 fSerialNumberString(NULL
)
26 memset(&fDescriptor
, 0, sizeof(fDescriptor
));
33 BUSBDevice::~BUSBDevice()
40 BUSBDevice::InitCheck()
42 return (fRawFD
>= 0 ? B_OK
: B_ERROR
);
47 BUSBDevice::SetTo(const char *path
)
53 fRawFD
= open(path
, O_RDWR
| O_CLOEXEC
);
59 usb_raw_command command
;
60 if (ioctl(fRawFD
, B_USB_RAW_COMMAND_GET_VERSION
, &command
, sizeof(command
))
61 || command
.version
.status
!= B_USB_RAW_PROTOCOL_VERSION
) {
66 command
.device
.descriptor
= &fDescriptor
;
67 if (ioctl(fRawFD
, B_USB_RAW_COMMAND_GET_DEVICE_DESCRIPTOR
, &command
,
68 sizeof(command
)) || command
.device
.status
!= B_USB_RAW_STATUS_SUCCESS
) {
73 fConfigurations
= new(std::nothrow
) BUSBConfiguration
*[
74 fDescriptor
.num_configurations
];
75 if (fConfigurations
== NULL
)
78 for (uint32 i
= 0; i
< fDescriptor
.num_configurations
; i
++) {
79 fConfigurations
[i
] = new(std::nothrow
) BUSBConfiguration(this, i
,
97 delete[] fManufacturerString
;
98 delete[] fProductString
;
99 delete[] fSerialNumberString
;
100 fManufacturerString
= fProductString
= fSerialNumberString
= NULL
;
102 if (fConfigurations
!= NULL
) {
103 for (int32 i
= 0; i
< fDescriptor
.num_configurations
; i
++)
104 delete fConfigurations
[i
];
106 delete[] fConfigurations
;
107 fConfigurations
= NULL
;
110 memset(&fDescriptor
, 0, sizeof(fDescriptor
));
115 BUSBDevice::Location() const
117 if (!fPath
|| strlen(fPath
) < 12)
125 BUSBDevice::IsHub() const
127 return fDescriptor
.device_class
== 0x09;
132 BUSBDevice::USBVersion() const
134 return fDescriptor
.usb_version
;
139 BUSBDevice::Class() const
141 return fDescriptor
.device_class
;
146 BUSBDevice::Subclass() const
148 return fDescriptor
.device_subclass
;
153 BUSBDevice::Protocol() const
155 return fDescriptor
.device_protocol
;
160 BUSBDevice::MaxEndpoint0PacketSize() const
162 return fDescriptor
.max_packet_size_0
;
167 BUSBDevice::VendorID() const
169 return fDescriptor
.vendor_id
;
174 BUSBDevice::ProductID() const
176 return fDescriptor
.product_id
;
181 BUSBDevice::Version() const
183 return fDescriptor
.device_version
;
188 BUSBDevice::ManufacturerString() const
190 if (fDescriptor
.manufacturer
== 0)
193 if (fManufacturerString
)
194 return fManufacturerString
;
196 fManufacturerString
= DecodeStringDescriptor(fDescriptor
.manufacturer
);
197 if (fManufacturerString
== NULL
)
200 return fManufacturerString
;
205 BUSBDevice::ProductString() const
207 if (fDescriptor
.product
== 0)
211 return fProductString
;
213 fProductString
= DecodeStringDescriptor(fDescriptor
.product
);
214 if (fProductString
== NULL
)
217 return fProductString
;
222 BUSBDevice::SerialNumberString() const
224 if (fDescriptor
.serial_number
== 0)
227 if (fSerialNumberString
)
228 return fSerialNumberString
;
230 fSerialNumberString
= DecodeStringDescriptor(fDescriptor
.serial_number
);
231 if (fSerialNumberString
== NULL
)
234 return fSerialNumberString
;
238 const usb_device_descriptor
*
239 BUSBDevice::Descriptor() const
246 BUSBDevice::GetStringDescriptor(uint32 index
,
247 usb_string_descriptor
*descriptor
, size_t length
) const
252 usb_raw_command command
;
253 command
.string
.descriptor
= descriptor
;
254 command
.string
.string_index
= index
;
255 command
.string
.length
= length
;
257 if (ioctl(fRawFD
, B_USB_RAW_COMMAND_GET_STRING_DESCRIPTOR
, &command
,
258 sizeof(command
)) || command
.string
.status
!= B_USB_RAW_STATUS_SUCCESS
)
261 return command
.string
.length
;
266 BUSBDevice::DecodeStringDescriptor(uint32 index
) const
269 usb_string_descriptor
*stringDescriptor
;
270 stringDescriptor
= (usb_string_descriptor
*)&buffer
;
272 size_t stringLength
= GetStringDescriptor(index
, stringDescriptor
,
273 sizeof(buffer
) - sizeof(usb_string_descriptor
));
275 if (stringLength
< 3)
278 // pseudo convert unicode string
279 stringLength
= (stringLength
- 2) / 2;
280 char *result
= new(std::nothrow
) char[stringLength
+ 1];
284 for (size_t i
= 0; i
< stringLength
; i
++)
285 result
[i
] = stringDescriptor
->string
[i
* 2];
286 result
[stringLength
] = 0;
292 BUSBDevice::GetDescriptor(uint8 type
, uint8 index
, uint16 languageID
,
293 void *data
, size_t length
) const
295 if (length
> 0 && data
== NULL
)
298 usb_raw_command command
;
299 command
.descriptor
.type
= type
;
300 command
.descriptor
.index
= index
;
301 command
.descriptor
.language_id
= languageID
;
302 command
.descriptor
.data
= data
;
303 command
.descriptor
.length
= length
;
305 if (ioctl(fRawFD
, B_USB_RAW_COMMAND_GET_DESCRIPTOR
, &command
,
306 sizeof(command
)) || command
.descriptor
.status
!= B_USB_RAW_STATUS_SUCCESS
)
309 return command
.descriptor
.length
;
314 BUSBDevice::CountConfigurations() const
316 return fDescriptor
.num_configurations
;
320 const BUSBConfiguration
*
321 BUSBDevice::ConfigurationAt(uint32 index
) const
323 if (index
>= fDescriptor
.num_configurations
|| fConfigurations
== NULL
)
326 return fConfigurations
[index
];
330 const BUSBConfiguration
*
331 BUSBDevice::ActiveConfiguration() const
333 if (fConfigurations
== NULL
)
336 return fConfigurations
[fActiveConfiguration
];
341 BUSBDevice::SetConfiguration(const BUSBConfiguration
*configuration
)
343 if (!configuration
|| configuration
->Index() >= fDescriptor
.num_configurations
)
346 usb_raw_command command
;
347 command
.config
.config_index
= configuration
->Index();
349 if (ioctl(fRawFD
, B_USB_RAW_COMMAND_SET_CONFIGURATION
, &command
,
350 sizeof(command
)) || command
.config
.status
!= B_USB_RAW_STATUS_SUCCESS
)
353 fActiveConfiguration
= configuration
->Index();
359 BUSBDevice::ControlTransfer(uint8 requestType
, uint8 request
, uint16 value
,
360 uint16 index
, uint16 length
, void *data
) const
362 if (length
> 0 && data
== NULL
)
365 usb_raw_command command
;
366 command
.control
.request_type
= requestType
;
367 command
.control
.request
= request
;
368 command
.control
.value
= value
;
369 command
.control
.index
= index
;
370 command
.control
.length
= length
;
371 command
.control
.data
= data
;
373 if (ioctl(fRawFD
, B_USB_RAW_COMMAND_CONTROL_TRANSFER
, &command
,
374 sizeof(command
)) || command
.control
.status
!= B_USB_RAW_STATUS_SUCCESS
)
377 return command
.control
.length
;
381 // definition of reserved virtual functions
382 void BUSBDevice::_ReservedUSBDevice1() {};
383 void BUSBDevice::_ReservedUSBDevice2() {};
384 void BUSBDevice::_ReservedUSBDevice3() {};
385 void BUSBDevice::_ReservedUSBDevice4() {};
386 void BUSBDevice::_ReservedUSBDevice5() {};