Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members
usbpp.cpp
00001 // -*- C++;indent-tabs-mode: t; tab-width: 4; c-basic-offset: 4; -*- 00002 /* 00003 * USB C++ bindings 00004 * 00005 * Copyright (C) 2003 Brad Hards <bradh@frogmouth.net> 00006 * 00007 * This library is covered by the LGPL, read LICENSE for details. 00008 */ 00009 00010 #include <errno.h> 00011 #include <cstdlib> 00012 00013 //remove after debugging 00014 #include <iostream> 00015 00016 #include "usbpp.h" 00017 00018 namespace USB { 00019 00020 Busses::Busses(void) 00021 { 00022 usb_init(); 00023 rescan(); 00024 } 00025 00026 void Busses::rescan(void) 00027 { 00028 struct usb_bus *bus; 00029 struct usb_device *dev; 00030 Bus *this_Bus; 00031 Device *this_Device; 00032 Configuration *this_Configuration; 00033 Interface *this_Interface; 00034 AltSetting *this_AltSetting; 00035 Endpoint *this_Endpoint; 00036 int i,j, k, l; 00037 00038 usb_find_busses(); 00039 usb_find_devices(); 00040 00041 for (bus = usb_get_busses(); bus; bus = bus->next) { 00042 std::string dirName(bus->dirname); 00043 00044 this_Bus = new Bus; 00045 this_Bus->setDirectoryName(dirName); 00046 push_back(this_Bus); 00047 00048 for (dev = bus->devices; dev; dev = dev->next) { 00049 int ret; 00050 std::string buf, fileName(dev->filename); 00051 usb_dev_handle *dev_handle; 00052 00053 this_Device = new Device; 00054 this_Device->setFileName(fileName); 00055 this_Device->setDescriptor(dev->descriptor); 00056 00057 dev_handle = usb_open(dev); 00058 00059 if (dev_handle) { 00060 00061 this_Device->setDevHandle(dev_handle); 00062 00063 if (dev->descriptor.iManufacturer) { 00064 ret = this_Device->string(buf, dev->descriptor.iManufacturer); 00065 if (ret > 0) 00066 this_Device->setVendor(buf); 00067 } 00068 00069 if (dev->descriptor.iProduct) { 00070 ret = this_Device->string(buf, dev->descriptor.iProduct); 00071 if (ret > 0) 00072 this_Device->setProduct(buf); 00073 } 00074 00075 if (dev->descriptor.iSerialNumber) { 00076 ret = this_Device->string(buf, dev->descriptor.iSerialNumber); 00077 if (ret > 0) 00078 this_Device->setSerialNumber(buf); 00079 } 00080 00081 } 00082 00083 this_Bus->push_back(this_Device); 00084 00085 for (i = 0; i < this_Device->numConfigurations(); i++) { 00086 00087 this_Configuration = new Configuration; 00088 this_Configuration->setDescriptor(dev->config[i]); 00089 this_Device->push_back(this_Configuration); 00090 00091 for (j = 0; j < this_Configuration->numInterfaces(); j ++) { 00092 00093 this_Interface = new Interface; 00094 this_Interface->setNumAltSettings((dev->config[i]).interface[j].num_altsetting); 00095 this_Interface->setParent(this_Device); 00096 this_Interface->setInterfaceNumber(j); 00097 this_Configuration->push_back(this_Interface); 00098 00099 for (k = 0; k < this_Interface->numAltSettings(); k ++) { 00100 00101 this_AltSetting = new AltSetting; 00102 this_AltSetting->setDescriptor((dev->config[i]).interface[j].altsetting[k]); 00103 this_Interface->push_back(this_AltSetting); 00104 00105 for (l=0; l < this_AltSetting->numEndpoints(); l++) { 00106 00107 this_Endpoint = new Endpoint; 00108 this_Endpoint->setDescriptor((dev->config[i]).interface[j].altsetting[k].endpoint[l]); 00109 this_Endpoint->setParent(this_Device); 00110 this_AltSetting->push_back(this_Endpoint); 00111 00112 } 00113 } 00114 } 00115 } 00116 } 00117 } 00118 } 00119 00120 std::list<Device *> Busses::match(u_int8_t class_code) 00121 { 00122 std::list<Device *> match_list; 00123 USB::Bus *bus; 00124 std::list<USB::Bus *>::const_iterator biter; 00125 00126 for (biter = begin(); biter != end(); biter++) { 00127 USB::Device *device; 00128 std::list<USB::Device *>::const_iterator diter; 00129 bus = *biter; 00130 00131 for (diter = bus->begin(); diter != bus->end(); diter++) { 00132 device = *diter; 00133 if (device->devClass() == class_code) { 00134 match_list.push_back(device); 00135 } 00136 } 00137 } 00138 return match_list; 00139 } 00140 00141 std::list<Device *> Busses::match(DeviceIDList devList) 00142 { 00143 std::list<Device *> match_list; 00144 USB::Bus *bus; 00145 std::list<USB::Bus *>::const_iterator biter; 00146 USB::DeviceID *this_ID; 00147 00148 for (biter = begin(); biter != end(); biter++) { 00149 USB::Device *device; 00150 std::list<USB::Device *>::const_iterator diter; 00151 00152 bus = *biter; 00153 for (diter = bus->begin(); diter != bus->end(); diter++) { 00154 DeviceIDList::iterator it; 00155 00156 device = *diter; 00157 00158 for (it = devList.begin(); it != devList.end(); it++) { 00159 if ( (device->idVendor() == (*it).vendor()) && 00160 (device->idProduct() == (*it).product()) ) { 00161 match_list.push_back(device); 00162 } 00163 } 00164 } 00165 } 00166 return match_list; 00167 } 00168 00169 std::string Bus::directoryName(void) 00170 { 00171 return m_directoryName; 00172 } 00173 00174 void Bus::setDirectoryName(std::string directoryName) 00175 { 00176 m_directoryName = directoryName; 00177 } 00178 00179 Device::~Device(void) 00180 { 00181 usb_close(m_handle); 00182 } 00183 00184 std::string Device::fileName(void) 00185 { 00186 return m_fileName; 00187 } 00188 00189 int Device::string(std::string &buf, int index, u_int16_t langID) 00190 { 00191 int retval; 00192 char tmpBuff[256]; 00193 00194 if ( 0 == langID) { 00195 /* we want the first lang ID available, so find out what it is */ 00196 retval = usb_get_string(m_handle, 0, 0, tmpBuff, sizeof(tmpBuff)); 00197 if (retval < 0) 00198 return retval; 00199 00200 if ( (retval < 4) || (tmpBuff[1] != USB_DT_STRING) ) 00201 return -EIO; 00202 00203 langID = tmpBuff[2] | (tmpBuff[3] << 8); 00204 } 00205 00206 retval = usb_get_string(m_handle, index, langID, tmpBuff, sizeof(tmpBuff)); 00207 00208 if (retval < 0) 00209 return retval; 00210 00211 if (tmpBuff[1] != USB_DT_STRING) 00212 return -EIO; 00213 00214 if (tmpBuff[0] > retval) 00215 return -EFBIG; 00216 00217 /* FIXME: Handle unicode? */ 00218 #if 0 00219 if (retval > 0) { 00220 std::string.setUnicode( (unsigned char *) &(tmpBuff[2]), (tmpBuff[0]/2 - 1) ); 00221 } 00222 #endif 00223 return retval; 00224 } 00225 00226 struct usb_dev_handle * Device::handle(void) 00227 { 00228 return m_handle; 00229 } 00230 00231 00232 #ifdef USE_UNTESTED_LIBUSBPP_METHODS 00233 int Device::reset(void) 00234 { 00235 return usb_reset( handle() ); 00236 } 00237 00238 int Device::setConfiguration(int configurationNumber) 00239 { 00240 return usb_set_configuration( handle(), configurationNumber ); 00241 } 00242 #endif /* USE_UNTESTED_LIBUSBPP_METHODS */ 00243 00244 u_int16_t Device::idVendor(void) 00245 { 00246 return m_descriptor.idVendor; 00247 } 00248 00249 u_int16_t Device::idProduct(void) 00250 { 00251 return m_descriptor.idProduct; 00252 } 00253 00254 u_int16_t Device::idRevision(void) 00255 { 00256 return m_descriptor.bcdDevice; 00257 } 00258 00259 u_int8_t Device::devClass(void) 00260 { 00261 return m_descriptor.bDeviceClass; 00262 } 00263 00264 u_int8_t Device::devSubClass(void) 00265 { 00266 return m_descriptor.bDeviceSubClass; 00267 } 00268 00269 u_int8_t Device::devProtocol(void) 00270 { 00271 return m_descriptor.bDeviceProtocol; 00272 } 00273 00274 std::string Device::Vendor(void) 00275 { 00276 return m_Vendor; 00277 } 00278 00279 std::string Device::Product(void) 00280 { 00281 return m_Product; 00282 } 00283 00284 std::string Device::SerialNumber(void) 00285 { 00286 return m_SerialNumber; 00287 } 00288 00289 void Device::setVendor(std::string vendor) 00290 { 00291 m_Vendor = vendor; 00292 } 00293 00294 void Device::setDevHandle(struct usb_dev_handle *device) 00295 { 00296 m_handle = device; 00297 } 00298 00299 void Device::setProduct(std::string product) 00300 { 00301 m_Product = product; 00302 } 00303 00304 void Device::setSerialNumber(std::string serialnumber) 00305 { 00306 m_SerialNumber = serialnumber; 00307 } 00308 00309 u_int8_t Device::numConfigurations(void) 00310 { 00311 return m_descriptor.bNumConfigurations; 00312 } 00313 00314 void Device::setFileName(std::string fileName) 00315 { 00316 m_fileName = fileName; 00317 } 00318 00319 void Device::setDescriptor(struct usb_device_descriptor descriptor) 00320 { 00321 m_descriptor = descriptor; 00322 } 00323 00324 Configuration *Device::firstConfiguration(void) 00325 { 00326 iter = begin(); 00327 return *iter++; 00328 } 00329 00330 Configuration *Device::nextConfiguration(void) 00331 { 00332 if (iter == end()) 00333 return NULL; 00334 00335 return *iter++; 00336 } 00337 00338 Configuration *Device::lastConfiguration(void) 00339 { 00340 return back(); 00341 } 00342 00343 int Device::controlTransfer(u_int8_t requestType, u_int8_t request, 00344 u_int16_t value, u_int16_t index, u_int16_t length, 00345 unsigned char *payload, int timeout) 00346 { 00347 return usb_control_msg(m_handle, requestType, request, value, index, (char *)payload, length, timeout); 00348 } 00349 00350 u_int8_t Configuration::numInterfaces(void) 00351 { 00352 return m_NumInterfaces; 00353 } 00354 00355 void Configuration::setDescriptor(struct usb_config_descriptor descriptor) 00356 { 00357 m_Length = descriptor.bLength; 00358 m_DescriptorType = descriptor.bDescriptorType; 00359 m_TotalLength = descriptor.wTotalLength; 00360 m_NumInterfaces = descriptor.bNumInterfaces; 00361 m_ConfigurationValue = descriptor.bConfigurationValue; 00362 m_Configuration = descriptor.iConfiguration; 00363 m_Attributes = descriptor.bmAttributes; 00364 m_MaxPower = descriptor.MaxPower; 00365 00366 } 00367 00368 void Configuration::dumpDescriptor(void) 00369 { 00370 printf(" wTotalLength: %d\n", m_TotalLength); 00371 printf(" bNumInterfaces: %d\n", m_NumInterfaces); 00372 printf(" bConfigurationValue: %d\n", m_ConfigurationValue); 00373 printf(" iConfiguration: %d\n", m_Configuration); 00374 printf(" bmAttributes: %02xh\n", m_Attributes); 00375 printf(" MaxPower: %d\n", m_MaxPower); 00376 } 00377 00378 Interface *Configuration::firstInterface(void) 00379 { 00380 iter = begin(); 00381 return *iter++; 00382 } 00383 00384 Interface *Configuration::nextInterface(void) 00385 { 00386 if (iter == end()) 00387 return NULL; 00388 00389 return *iter++; 00390 } 00391 00392 Interface *Configuration::lastInterface(void) 00393 { 00394 return back(); 00395 } 00396 00397 #ifdef LIBUSB_HAS_GET_DRIVER_NP 00398 int Interface::driverName(std::string &driver) 00399 { 00400 int retval; 00401 char tmpString[256]; 00402 00403 retval = usb_get_driver_np(m_parent->handle(), m_interfaceNumber, tmpString, sizeof(tmpString)); 00404 if (retval == 0) { 00405 std::string buf(tmpString); 00406 00407 driver = buf; 00408 } 00409 return retval; 00410 } 00411 #endif 00412 00413 00414 #ifdef USE_UNTESTED_LIBUSBPP_METHODS 00415 int Interface::claim(void) 00416 { 00417 return usb_claim_interface(m_parent->handle(), m_interfaceNumber); 00418 } 00419 00420 int Interface::release(void) 00421 { 00422 return usb_claim_interface(m_parent->handle(), m_interfaceNumber); 00423 } 00424 00425 int Interface::setAltSetting(int altSettingNumber) 00426 { 00427 return usb_set_altinterface(m_parent->handle(), altSettingNumber); 00428 } 00429 #endif /* USE_UNTESTED_LIBUSBPP_METHODS */ 00430 00431 u_int8_t Interface::numAltSettings(void) 00432 { 00433 return m_numAltSettings; 00434 } 00435 00436 void Interface::setNumAltSettings(u_int8_t num_altsetting) 00437 { 00438 m_numAltSettings = num_altsetting; 00439 } 00440 00441 void Interface::setInterfaceNumber(int interfaceNumber) 00442 { 00443 m_interfaceNumber = interfaceNumber; 00444 } 00445 00446 void Interface::setParent(Device *parent) 00447 { 00448 m_parent = parent; 00449 } 00450 00451 AltSetting *Interface::firstAltSetting(void) 00452 { 00453 iter = begin(); 00454 return *iter++; 00455 } 00456 00457 AltSetting *Interface::nextAltSetting(void) 00458 { 00459 if (iter == end()) 00460 return NULL; 00461 00462 return *iter++; 00463 } 00464 00465 AltSetting *Interface::lastAltSetting(void) 00466 { 00467 return back(); 00468 } 00469 00470 void AltSetting::setDescriptor(struct usb_interface_descriptor descriptor) 00471 { 00472 m_Length = descriptor.bLength; 00473 m_DescriptorType = descriptor.bDescriptorType; 00474 m_InterfaceNumber = descriptor.bInterfaceNumber; 00475 m_AlternateSetting = descriptor.bAlternateSetting; 00476 m_NumEndpoints = descriptor.bNumEndpoints; 00477 m_InterfaceClass = descriptor.bInterfaceClass; 00478 m_InterfaceSubClass = descriptor.bInterfaceSubClass; 00479 m_InterfaceProtocol = descriptor.bInterfaceProtocol; 00480 m_Interface = descriptor.iInterface; 00481 } 00482 00483 void AltSetting::dumpDescriptor(void) 00484 { 00485 printf(" bInterfaceNumber: %d\n", m_InterfaceNumber); 00486 printf(" bAlternateSetting: %d\n", m_AlternateSetting); 00487 printf(" bNumEndpoints: %d\n", m_NumEndpoints); 00488 printf(" bInterfaceClass: %d\n", m_InterfaceClass); 00489 printf(" bInterfaceSubClass: %d\n", m_InterfaceSubClass); 00490 printf(" bInterfaceProtocol: %d\n", m_InterfaceProtocol); 00491 printf(" iInterface: %d\n", m_Interface); 00492 } 00493 00494 Endpoint *AltSetting::firstEndpoint(void) 00495 { 00496 iter = begin(); 00497 return *iter++; 00498 } 00499 00500 Endpoint *AltSetting::nextEndpoint(void) 00501 { 00502 if (iter == end()) 00503 return NULL; 00504 00505 return *iter++; 00506 } 00507 00508 Endpoint *AltSetting::lastEndpoint(void) 00509 { 00510 return back(); 00511 } 00512 00513 u_int8_t AltSetting::numEndpoints(void) 00514 { 00515 return m_NumEndpoints; 00516 } 00517 00518 void Endpoint::setDescriptor(struct usb_endpoint_descriptor descriptor) 00519 { 00520 m_EndpointAddress = descriptor.bEndpointAddress; 00521 m_Attributes = descriptor.bmAttributes; 00522 m_MaxPacketSize = descriptor.wMaxPacketSize; 00523 m_Interval = descriptor.bInterval; 00524 m_Refresh = descriptor.bRefresh; 00525 m_SynchAddress = descriptor.bSynchAddress; 00526 } 00527 00528 void Endpoint::setParent(Device *parent) 00529 { 00530 m_parent = parent; 00531 } 00532 00533 #ifdef USE_UNTESTED_LIBUSBPP_METHODS 00534 int Endpoint::bulkWrite(unsigned char *message, int timeout) 00535 { 00536 return usb_bulk_write(m_parent->handle(), m_EndpointAddress, message.data(), 00537 message.size(), timeout); 00538 } 00539 00540 int Endpoint::bulkRead(int length, unsigned char *message, int timeout) 00541 { 00542 char * buf; 00543 int res; 00544 00545 buf = (char *) malloc(length); 00546 res = usb_bulk_read(m_parent->handle(), m_EndpointAddress, buf, length, timeout); 00547 00548 if (res > 0) { 00549 message.resize(length); 00550 message.duplicate(buf, res); 00551 } 00552 00553 return res; 00554 } 00555 00556 int Endpoint::reset(void) 00557 { 00558 return usb_resetep(m_parent->handle(), m_EndpointAddress); 00559 } 00560 00561 int Endpoint::clearHalt(void) 00562 { 00563 return usb_clear_halt(m_parent->handle(), m_EndpointAddress); 00564 } 00565 00566 #endif /* USE_UNTESTED_LIBUSBPP_METHODS */ 00567 00568 void Endpoint::dumpDescriptor(void) 00569 { 00570 printf(" bEndpointAddress: %02xh\n", m_EndpointAddress); 00571 printf(" bmAttributes: %02xh\n", m_Attributes); 00572 printf(" wMaxPacketSize: %d\n", m_MaxPacketSize); 00573 printf(" bInterval: %d\n", m_Interval); 00574 printf(" bRefresh: %d\n", m_Refresh); 00575 printf(" bSynchAddress: %d\n", m_SynchAddress); 00576 } 00577 00578 DeviceID::DeviceID(u_int16_t vendor, u_int16_t product) 00579 { 00580 m_vendor = vendor; 00581 m_product = product; 00582 } 00583 00584 u_int16_t DeviceID::vendor(void) 00585 { 00586 return m_vendor; 00587 } 00588 00589 u_int16_t DeviceID::product(void) 00590 { 00591 return m_product; 00592 } 00593 }