Fixed C++ errors and warnings reported by cppcheck
[barry.git] / src / usbwrap_libusb.cc
blobf6a3cc0f86534f08d39f98f8ff69628f866a3755
1 ///
2 /// \file usbwrap_libusb.cc
3 /// USB API wrapper for libusb version 0.1
4 ///
6 /*
7 Copyright (C) 2005-2013, Chris Frey
8 Portions Copyright (C) 2011, RealVNC Ltd.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License in the COPYING file at the
20 root directory of this project for more details.
23 #include "i18n.h"
25 #include "usbwrap_libusb.h"
27 #include "debug.h"
28 #include "data.h"
29 #include <errno.h>
30 #include <string.h>
31 #include <iostream>
32 #include <sstream>
33 #include <algorithm>
35 #ifndef __DEBUG_MODE__
36 #define __DEBUG_MODE__
37 #endif
38 #include "debug.h"
40 namespace Usb {
42 // helper function to make deleting pointers in maps and vectors easier
43 template<typename T> static void deletePtr(T* ptr) {
44 delete ptr;
47 template<typename K, typename T> static void deleteMapPtr(std::pair<K,T*> ptr) {
48 delete ptr.second;
51 ///////////////////////////////////////////////////////////////////////////////
52 // Static functions
54 std::string LibraryInterface::GetLastErrorString(int /*libusb_errcode*/)
56 // Errcode is unused by libusb, so just call the last error
57 return std::string(usb_strerror());
60 int LibraryInterface::TranslateErrcode(int libusb_errcode)
62 // libusb errcode == system errcode
63 return libusb_errcode;
66 bool LibraryInterface::Init(int *libusb_errno)
68 // if the environment variable USB_DEBUG is set, that
69 // level value will be used instead of our 9 below...
70 // if you need to *force* this to 9, call SetDataDump(true)
71 // after Init()
72 usb_init();
73 // Can never fail, so return success
74 return true;
77 void LibraryInterface::Uninit()
79 // Nothing to do
82 void LibraryInterface::SetDataDump(bool data_dump_mode)
84 if( data_dump_mode )
85 usb_set_debug(9);
86 else
87 usb_set_debug(0);
90 ///////////////////////////////////////////////////////////////////////////////
91 // DeviceID
93 DeviceID::DeviceID(DeviceIDImpl* impl)
94 : m_impl(impl)
98 DeviceID::~DeviceID()
102 const char* DeviceID::GetBusName() const
104 return m_impl->m_dev->bus->dirname;
107 uint16_t DeviceID::GetNumber() const
109 return m_impl->m_dev->devnum;
112 const char* DeviceID::GetFilename() const
114 return m_impl->m_dev->filename;
117 uint16_t DeviceID::GetIdProduct() const
119 return m_impl->m_dev->descriptor.idProduct;
122 std::string DeviceID::GetUsbName() const
124 // for libusb 0.1, we need both the bus name and the filename
125 // and we stay away from the product ID, since that requires
126 // communication with the device, which may not be possible
127 // in error conditions.
128 std::ostringstream oss;
129 oss << GetBusName() << ":" << GetFilename();
130 return oss.str();
133 ///////////////////////////////////////////////////////////////////////////////
134 // DeviceList
136 DeviceList::DeviceList()
137 : m_impl(new DeviceListImpl())
139 // Work out what devices are on the bus at the moment
140 usb_find_busses();
141 usb_find_devices();
142 struct usb_bus* busses = usb_get_busses();
143 for( ; busses; busses = busses->next ) {
144 struct usb_device* dev = busses->devices;
145 for( ; dev; dev = dev->next ) {
146 // Add the device to the list of devices
147 std::auto_ptr<DeviceIDImpl> impl( new DeviceIDImpl() );
148 impl->m_dev = dev;
149 DeviceID devID(impl.release());
150 m_impl->m_devices.push_back(devID);
155 DeviceList::~DeviceList()
160 static bool ToNum(const char *str, long &num)
162 char *end = 0;
163 num = strtol(str, &end, 10);
164 return num >= 0 && // no negative numbers
165 num != LONG_MIN && num != LONG_MAX && // no overflow
166 str != end && *end == '\0'; // whole string valid
170 // Linux treats bus and device path names as numbers, sometimes left
171 // padded with zeros. Other platforms, such as Windows, use strings,
172 // such as "bus-1" or similar.
174 // Here we try to convert each string to a number, and if successful,
175 // compare them. If unable to convert, then compare as strings.
176 // This way, "3" == "003" and "bus-foobar" == "bus-foobar".
178 static bool NameCompare(const char *n1, const char *n2)
180 long l1, l2;
181 if( ToNum(n1, l1) && ToNum(n2, l2) ) {
182 return l1 == l2;
184 else {
185 return strcmp(n1, n2) == 0;
189 std::vector<DeviceID> DeviceList::MatchDevices(int vendor, int product,
190 const char *busname, const char *devname)
192 std::vector<DeviceID> ret;
194 std::vector<DeviceID>::iterator iter = m_impl->m_devices.begin();
196 for( ; iter != m_impl->m_devices.end() ; ++iter ) {
197 struct usb_device* dev = iter->m_impl->m_dev;
199 // only search on given bus
200 if( busname && !NameCompare(busname, dev->bus->dirname) )
201 continue;
203 // search for specific device
204 if( devname && !NameCompare(devname, dev->filename) )
205 continue;
207 // is there a match?
208 if( dev->descriptor.idVendor == vendor &&
209 ( dev->descriptor.idProduct == product ||
210 product == PRODUCT_ANY )) {
211 ret.push_back(*iter);
215 return ret;
218 ///////////////////////////////////////////////////////////////////////////////
219 // Device
221 Device::Device(const Usb::DeviceID& id, int timeout)
222 : m_id(id),
223 m_handle(new DeviceHandle()),
224 m_timeout(timeout),
225 m_lasterror(0)
227 dout("usb_open(" << std::dec << id.m_impl.get() << ")");
228 if( !id.m_impl.get() )
229 throw Error(_("invalid USB device ID"));
230 m_handle->m_handle = usb_open(id.m_impl->m_dev);
231 if( !m_handle->m_handle )
232 throw Error(_("Failed to open USB device. Please check your system's USB device permissions."));
235 Device::~Device()
237 dout("usb_close(" << std::dec << m_handle->m_handle << ")");
238 usb_close(m_handle->m_handle);
241 bool Device::SetConfiguration(unsigned char cfg)
243 dout("usb_set_configuration(" << std::dec << m_handle->m_handle << ", 0x" << std::hex << (unsigned int) cfg << ")");
244 int ret = usb_set_configuration(m_handle->m_handle, cfg);
245 m_lasterror = ret;
246 return ret >= 0;
249 bool Device::ClearHalt(int ep)
251 dout("usb_clear_halt(" << std::dec << m_handle->m_handle << ", 0x" << std::hex << ep << ")");
252 int ret = usb_clear_halt(m_handle->m_handle, ep);
253 m_lasterror = ret;
254 return ret >= 0;
257 bool Device::Reset()
259 dout("usb_reset(" << std::dec << m_handle->m_handle << ")");
260 int ret = usb_reset(m_handle->m_handle);
261 m_lasterror = ret;
262 return ret == 0;
265 bool Device::BulkRead(int ep, Barry::Data &data, int timeout)
267 int ret;
268 do {
269 data.QuickZap();
270 ret = usb_bulk_read(m_handle->m_handle, ep,
271 (char*) data.GetBuffer(), data.GetBufSize(),
272 timeout == -1 ? m_timeout : timeout);
273 if( ret < 0 && ret != -EINTR && ret != -EAGAIN ) {
274 m_lasterror = ret;
275 if( ret == -ETIMEDOUT )
276 throw Timeout(ret, _("Timeout in usb_bulk_read"));
277 else {
278 std::ostringstream oss;
279 oss << _("Error in usb_bulk_read(")
280 << m_handle->m_handle << ", "
281 << ep << ", buf, "
282 << data.GetBufSize() << ")";
283 throw Error(ret, oss.str());
286 else if( ret > 0 )
287 data.ReleaseBuffer(ret);
288 } while( ret == -EINTR || ret == -EAGAIN );
290 return ret >= 0;
293 bool Device::BulkWrite(int ep, const Barry::Data &data, int timeout)
295 ddout("BulkWrite to endpoint 0x" << std::hex << ep << ":\n" << data);
296 int ret;
297 do {
298 ret = usb_bulk_write(m_handle->m_handle, ep,
299 (char*) data.GetData(), data.GetSize(),
300 timeout == -1 ? m_timeout : timeout);
301 if( ret < 0 && ret != -EINTR && ret != -EAGAIN ) {
302 m_lasterror = ret;
303 if( ret == -ETIMEDOUT )
304 throw Timeout(ret, _("Timeout in usb_bulk_write (1)"));
305 else
306 throw Error(ret, _("Error in usb_bulk_write (1)"));
308 } while( ret == -EINTR || ret == -EAGAIN );
310 return ret >= 0;
313 bool Device::BulkWrite(int ep, const void *data, size_t size, int timeout)
315 #ifdef __DEBUG_MODE__
316 Barry::Data dump(data, size);
317 ddout("BulkWrite to endpoint 0x" << std::hex << ep << ":\n" << dump);
318 #endif
320 int ret;
321 do {
322 ret = usb_bulk_write(m_handle->m_handle, ep,
323 (char*) data, size,
324 timeout == -1 ? m_timeout : timeout);
325 if( ret < 0 && ret != -EINTR && ret != -EAGAIN ) {
326 m_lasterror = ret;
327 if( ret == -ETIMEDOUT )
328 throw Timeout(ret, _("Timeout in usb_bulk_write (2)"));
329 else
330 throw Error(ret, _("Error in usb_bulk_write (2)"));
332 } while( ret == -EINTR || ret == -EAGAIN );
334 return ret >= 0;
337 bool Device::InterruptRead(int ep, Barry::Data &data, int timeout)
339 int ret;
340 do {
341 data.QuickZap();
342 ret = usb_interrupt_read(m_handle->m_handle, ep,
343 (char*) data.GetBuffer(), data.GetBufSize(),
344 timeout == -1 ? m_timeout : timeout);
345 if( ret < 0 && ret != -EINTR && ret != -EAGAIN ) {
346 m_lasterror = ret;
347 if( ret == -ETIMEDOUT )
348 throw Timeout(ret, _("Timeout in usb_interrupt_read"));
349 else
350 throw Error(ret, _("Error in usb_interrupt_read"));
352 else if( ret > 0 )
353 data.ReleaseBuffer(ret);
354 } while( ret == -EINTR || ret == -EAGAIN );
356 return ret >= 0;
359 bool Device::InterruptWrite(int ep, const Barry::Data &data, int timeout)
361 ddout("InterruptWrite to endpoint 0x" << std::hex << ep << ":\n" << data);
363 int ret;
364 do {
365 ret = usb_interrupt_write(m_handle->m_handle, ep,
366 (char*) data.GetData(), data.GetSize(),
367 timeout == -1 ? m_timeout : timeout);
368 if( ret < 0 && ret != -EINTR && ret != -EAGAIN ) {
369 m_lasterror = ret;
370 if( ret == -ETIMEDOUT )
371 throw Timeout(ret, _("Timeout in usb_interrupt_write"));
372 else
373 throw Error(ret, _("Error in usb_interrupt_write"));
375 } while( ret == -EINTR || ret == -EAGAIN );
377 return ret >= 0;
381 // BulkDrain
383 /// Reads anything available on the given endpoint, with a low timeout,
384 /// in order to clear any pending reads.
386 void Device::BulkDrain(int ep, int timeout)
388 try {
389 Barry::Data data;
390 while( BulkRead(ep, data, timeout) )
393 catch( Usb::Error & ) {}
397 // GetConfiguration
399 /// Uses the GET_CONFIGURATION control message to determine the currently
400 /// selected USB configuration, returning it in the cfg argument.
401 /// If unsuccessful, returns false.
403 bool Device::GetConfiguration(unsigned char &cfg)
405 int result = usb_control_msg(m_handle->m_handle, 0x80, USB_REQ_GET_CONFIGURATION, 0, 0,
406 (char*) &cfg, 1, m_timeout);
407 m_lasterror = result;
408 return result >= 0;
411 // Returns the current power level of the device, or 0 if unknown
412 int Device::GetPowerLevel()
414 if( !m_id.m_impl->m_dev->config ||
415 !m_id.m_impl->m_dev->descriptor.bNumConfigurations < 1 )
416 return 0;
418 return m_id.m_impl->m_dev->config[0].MaxPower;
421 std::string Device::GetSimpleSerialNumber()
423 std::string sn;
424 char buf[1024];
425 int ret = usb_get_string_simple(m_handle->m_handle,
426 m_id.m_impl->m_dev->descriptor.iSerialNumber, buf, sizeof(buf));
427 if( ret > 0 )
428 sn.assign(buf, ret);
429 return sn;
432 bool Device::IsAttachKernelDriver(int iface)
434 int ret;
435 char buffer[64];
437 #if LIBUSB_HAS_GET_DRIVER_NP
438 ret = usb_get_driver_np(m_handle->m_handle, iface, buffer, sizeof(buffer));
439 if (ret == 0) {
440 dout("interface (" << m_handle->m_handle << ", 0x" << std::hex << iface
441 << ") already claimed by driver \"" << buffer << "\"");
442 return true;
444 m_lasterror = ret;
445 #else
446 m_lasterror = -ENOSYS;
447 #endif
449 return false;
452 // Requests that the kernel driver is detached, returning false on failure
453 bool Device::DetachKernelDriver(int iface)
455 #if LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
456 int result = usb_detach_kernel_driver_np(m_handle->m_handle, iface);
457 m_lasterror = result;
458 return result >= 0;
459 #else
460 m_lasterror = -ENOSYS;
461 return false;
462 #endif
465 // Sends a control message to the device, returning false on failure
466 bool Device::ControlMsg(int requesttype, int request, int value,
467 int index, char *bytes, int size, int timeout)
469 int result = usb_control_msg(m_handle->m_handle,
470 requesttype, request, value, index,
471 bytes, size, timeout);
472 m_lasterror = result;
473 return result >= 0;
477 int Device::FindInterface(int ifaceClass)
479 struct usb_config_descriptor *cfg = m_id.m_impl->m_dev->config;
481 if( cfg ) {
483 for( unsigned i = 0; cfg->interface && i < cfg->bNumInterfaces; i++ ) {
484 struct usb_interface *iface = &cfg->interface[i];
485 for( int a = 0; iface->altsetting && a < iface->num_altsetting; a++ ) {
486 struct usb_interface_descriptor *id = &iface->altsetting[a];
487 if( id->bInterfaceClass == ifaceClass )
488 return id->bInterfaceNumber;
493 return -1;
497 ///////////////////////////////////////////////////////////////////////////////
498 // Interface
500 Interface::Interface(Device &dev, int iface)
501 : m_dev(dev), m_iface(iface)
503 dout("usb_claim_interface(" << dev.GetHandle()->m_handle << ", 0x" << std::hex << iface << ")");
504 int ret = usb_claim_interface(dev.GetHandle()->m_handle, iface);
505 if( ret < 0 )
506 throw Error(ret, _("claim interface failed"));
509 Interface::~Interface()
511 dout("usb_release_interface(" << m_dev.GetHandle()->m_handle << ", 0x" << std::hex << m_iface << ")");
512 usb_release_interface(m_dev.GetHandle()->m_handle, m_iface);
516 // SetAltInterface
518 /// Uses the usb_set_altinterface() function to set the currently
519 /// selected USB alternate setting of the current interface.
520 /// The iface parameter passed in should be a value specified
521 /// in the bAlternateSetting descriptor field.
522 /// If unsuccessful, returns false.
524 bool Interface::SetAltInterface(int altSetting)
526 int result = usb_set_altinterface(m_dev.GetHandle()->m_handle, altSetting);
527 m_dev.SetLastError(result);
528 return result >= 0;
531 //////////////////////////////////////////////////////////////////
532 // DeviceDescriptor
534 DeviceDescriptor::DeviceDescriptor(DeviceID& devid)
535 : m_impl(new DeviceDescriptorImpl())
537 if( !devid.m_impl.get() ) {
538 dout("DeviceDescriptor: empty devid");
539 return;
541 // Copy the descriptor over to our memory
542 m_impl->m_dev = devid.m_impl->m_dev;
543 m_impl->m_desc = devid.m_impl->m_dev->descriptor;
544 dout("device_desc loaded"
545 << "\nbLength: " << std::dec << (unsigned int) m_impl->m_desc.bLength
546 << "\nbDescriptorType: " << std::dec << (unsigned int) m_impl->m_desc.bDescriptorType
547 << "\nbcdUSB: 0x" << std::hex << (unsigned int) m_impl->m_desc.bcdUSB
548 << "\nbDeviceClass: " << std::dec << (unsigned int) m_impl->m_desc.bDeviceClass
549 << "\nbDeviceSubClass: " << std::dec << (unsigned int) m_impl->m_desc.bDeviceSubClass
550 << "\nbDeviceProtocol: " << std::dec << (unsigned int) m_impl->m_desc.bDeviceProtocol
551 << "\nbMaxPacketSize0: " << std::dec << (unsigned int) m_impl->m_desc.bMaxPacketSize0
552 << "\nidVendor: 0x" << std::hex << (unsigned int) m_impl->m_desc.idVendor
553 << "\nidProduct: 0x" << std::hex << (unsigned int) m_impl->m_desc.idProduct
554 << "\nbcdDevice: 0x" << std::hex << (unsigned int) m_impl->m_desc.bcdDevice
555 << "\niManufacturer: " << std::dec << (unsigned int) m_impl->m_desc.iManufacturer
556 << "\niProduct: " << std::dec << (unsigned int) m_impl->m_desc.iProduct
557 << "\niSerialNumber: " << std::dec << (unsigned int) m_impl->m_desc.iSerialNumber
558 << "\nbNumConfigurations: " << std::dec << (unsigned int) m_impl->m_desc.bNumConfigurations
559 << "\n"
562 // Create all the configs
563 for( int i = 0; i < m_impl->m_desc.bNumConfigurations; ++i ) {
564 std::auto_ptr<ConfigDescriptor> ptr(new ConfigDescriptor(*this, i));
565 (*this)[ptr->GetNumber()] = ptr.get();
566 ptr.release();
570 DeviceDescriptor::~DeviceDescriptor()
572 // Delete any pointers in the map
573 std::for_each(begin(),
574 end(),
575 deleteMapPtr<int, ConfigDescriptor>);
578 ///////////////////////////////////////////////////////////////////
579 // ConfigDescriptor
581 ConfigDescriptor::ConfigDescriptor(DeviceDescriptor& dev, int cfgnumber)
582 : m_impl(new ConfigDescriptorImpl())
584 // Copy the config descriptor locally
585 m_impl->m_desc = dev.m_impl->m_dev->config[cfgnumber];
586 dout(" config_desc #" << std::dec << cfgnumber << " loaded"
587 << "\nbLength: " << std::dec << (unsigned int) m_impl->m_desc.bLength
588 << "\nbDescriptorType: " << std::dec << (unsigned int) m_impl->m_desc.bDescriptorType
589 << "\nwTotalLength: " << std::dec << (unsigned int) m_impl->m_desc.wTotalLength
590 << "\nbNumInterfaces: " << std::dec << (unsigned int) m_impl->m_desc.bNumInterfaces
591 << "\nbConfigurationValue: " << std::dec << (unsigned int) m_impl->m_desc.bConfigurationValue
592 << "\niConfiguration: " << std::dec << (unsigned int) m_impl->m_desc.iConfiguration
593 << "\nbmAttributes: 0x" << std::hex << (unsigned int) m_impl->m_desc.bmAttributes
594 << "\nMaxPower: " << std::dec << (unsigned int) m_impl->m_desc.MaxPower
595 << "\n"
598 // just for debugging purposes, check for extra descriptors, and
599 // dump them to dout if they exist
600 if( m_impl->m_desc.extra ) {
601 dout("while parsing config descriptor, found a block of extra descriptors:");
602 Barry::Data data(m_impl->m_desc.extra, m_impl->m_desc.extralen);
603 dout(data);
606 // Create all the interfaces
607 for( int i = 0; i < m_impl->m_desc.bNumInterfaces; ++i ) {
608 struct usb_interface* interface = &(m_impl->m_desc.interface[i]);
609 if( !interface->altsetting ) {
610 dout("ConfigDescriptor: empty altsetting");
611 // some devices are buggy and return a higher bNumInterfaces
612 // than the number of interfaces available... in this case
613 // we just skip and continue
614 continue;
616 for( int j = 0; j < interface->num_altsetting; ++j ) {
617 std::auto_ptr<InterfaceDescriptor> ptr(
618 new InterfaceDescriptor(*this, i, j));
619 (*this)[ptr->GetNumber()] = ptr.get();
620 ptr.release();
625 ConfigDescriptor::~ConfigDescriptor()
627 // Delete any pointers in the map
628 std::for_each(begin(),
629 end(),
630 deleteMapPtr<int, InterfaceDescriptor>);
633 uint8_t ConfigDescriptor::GetNumber() const {
634 return m_impl->m_desc.bConfigurationValue;
637 /////////////////////////////////////////////////////////////////////////
638 // InterfaceDescriptor
640 InterfaceDescriptor::InterfaceDescriptor(ConfigDescriptor& cfg,
641 int interface, int altsetting)
642 : m_impl(new InterfaceDescriptorImpl())
644 // Copy the descriptor
645 m_impl->m_desc = cfg.m_impl->m_desc
646 .interface[interface]
647 .altsetting[altsetting];
648 dout(" interface_desc #" << std::dec << interface << " loaded"
649 << "\nbLength: " << std::dec << (unsigned) m_impl->m_desc.bLength
650 << "\nbDescriptorType: " << std::dec << (unsigned) m_impl->m_desc.bDescriptorType
651 << "\nbInterfaceNumber: " << std::dec << (unsigned) m_impl->m_desc.bInterfaceNumber
652 << "\nbAlternateSetting: " << std::dec << (unsigned) m_impl->m_desc.bAlternateSetting
653 << "\nbNumEndpoints: " << std::dec << (unsigned) m_impl->m_desc.bNumEndpoints
654 << "\nbInterfaceClass: " << std::dec << (unsigned) m_impl->m_desc.bInterfaceClass
655 << "\nbInterfaceSubClass: " << std::dec << (unsigned) m_impl->m_desc.bInterfaceSubClass
656 << "\nbInterfaceProtocol: " << std::dec << (unsigned) m_impl->m_desc.bInterfaceProtocol
657 << "\niInterface: " << std::dec << (unsigned) m_impl->m_desc.iInterface
658 << "\n"
661 if( !m_impl->m_desc.endpoint ) {
662 dout("InterfaceDescriptor: empty interface pointer");
663 return;
666 // Create all the endpoints
667 for( int i = 0; i < m_impl->m_desc.bNumEndpoints; ++i ) {
668 std::auto_ptr<EndpointDescriptor> ptr (
669 new EndpointDescriptor(*this, i));
670 this->push_back(ptr.get());
671 ptr.release();
674 // just for debugging purposes, check for extra descriptors, and
675 // dump them to dout if they exist
676 if( m_impl->m_desc.extra ) {
677 dout("while parsing interface descriptor, found a block of extra descriptors:");
678 Barry::Data data(m_impl->m_desc.extra, m_impl->m_desc.extralen);
679 dout(data);
683 InterfaceDescriptor::~InterfaceDescriptor()
685 // Delete any pointers in the vector
686 std::for_each(begin(),
687 end(),
688 deletePtr<EndpointDescriptor>);
691 uint8_t InterfaceDescriptor::GetClass() const
693 return m_impl->m_desc.bInterfaceClass;
696 uint8_t InterfaceDescriptor::GetNumber() const
698 return m_impl->m_desc.bInterfaceNumber;
701 uint8_t InterfaceDescriptor::GetAltSetting() const
703 return m_impl->m_desc.bAlternateSetting;
706 /////////////////////////////////////////////////////////////////////////////////
707 // EndpointDescriptor
709 EndpointDescriptor::EndpointDescriptor(InterfaceDescriptor& interface, int endpoint)
710 : m_impl(new EndpointDescriptorImpl()),
711 m_read(false),
712 m_addr(0),
713 m_type(InvalidType)
715 // Copy the descriptor
716 m_impl->m_desc = interface.m_impl->m_desc.endpoint[endpoint];
717 dout(" endpoint_desc #" << std::dec << endpoint << " loaded"
718 << "\nbLength: " << std::dec << (unsigned ) m_impl->m_desc.bLength
719 << "\nbDescriptorType: " << std::dec << (unsigned ) m_impl->m_desc.bDescriptorType
720 << "\nbEndpointAddress: 0x" << std::hex << (unsigned ) m_impl->m_desc.bEndpointAddress
721 << "\nbmAttributes: 0x" << std::hex << (unsigned ) m_impl->m_desc.bmAttributes
722 << "\nwMaxPacketSize: " << std::dec << (unsigned ) m_impl->m_desc.wMaxPacketSize
723 << "\nbInterval: " << std::dec << (unsigned ) m_impl->m_desc.bInterval
724 << "\nbRefresh: " << std::dec << (unsigned ) m_impl->m_desc.bRefresh
725 << "\nbSynchAddress: " << std::dec << (unsigned ) m_impl->m_desc.bSynchAddress
726 << "\n"
728 // Set up variables
729 m_read = ((m_impl->m_desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) != 0);
730 m_addr = (m_impl->m_desc.bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK);
731 int type = (m_impl->m_desc.bmAttributes & USB_ENDPOINT_TYPE_MASK);
732 m_type = static_cast<Usb::EndpointDescriptor::EpType>(type);
734 // just for debugging purposes, check for extra descriptors, and
735 // dump them to dout if they exist
736 if( m_impl->m_desc.extra ) {
737 dout("while parsing endpoint descriptor, found a block of extra descriptors:");
738 Barry::Data data(m_impl->m_desc.extra, m_impl->m_desc.extralen);
739 dout(data);
743 EndpointDescriptor::~EndpointDescriptor()
747 } // namespace Usb