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