1# Copyright (C) 2009-2014 Wander Lairson Costa 2# 3# The following terms apply to all files associated 4# with the software unless explicitly disclaimed in individual files. 5# 6# The authors hereby grant permission to use, copy, modify, distribute, 7# and license this software and its documentation for any purpose, provided 8# that existing copyright notices are retained in all copies and that this 9# notice is included verbatim in any distributions. No written agreement, 10# license, or royalty fee is required for any of the authorized uses. 11# Modifications to this software may be copyrighted by their authors 12# and need not follow the licensing terms described here, provided that 13# the new terms are clearly indicated on the first page of each file where 14# they apply. 15# 16# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY 17# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 18# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY 19# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE 20# POSSIBILITY OF SUCH DAMAGE. 21# 22# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, 23# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, 24# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE 25# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE 26# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 27# MODIFICATIONS. 28 29from ctypes import * 30import ctypes.util 31import usb.util 32from usb._debug import methodtrace 33import logging 34import errno 35import sys 36import usb._interop as _interop 37import usb._objfinalizer as _objfinalizer 38import usb.util as util 39import usb.libloader 40from usb.core import USBError 41 42__author__ = 'Wander Lairson Costa' 43 44__all__ = [ 45 'get_backend' 46 'OPENUSB_SUCCESS' 47 'OPENUSB_PLATFORM_FAILURE' 48 'OPENUSB_NO_RESOURCES' 49 'OPENUSB_NO_BANDWIDTH' 50 'OPENUSB_NOT_SUPPORTED' 51 'OPENUSB_HC_HARDWARE_ERROR' 52 'OPENUSB_INVALID_PERM' 53 'OPENUSB_BUSY' 54 'OPENUSB_BADARG' 55 'OPENUSB_NOACCESS' 56 'OPENUSB_PARSE_ERROR' 57 'OPENUSB_UNKNOWN_DEVICE' 58 'OPENUSB_INVALID_HANDLE' 59 'OPENUSB_SYS_FUNC_FAILURE' 60 'OPENUSB_NULL_LIST' 61 'OPENUSB_CB_CONTINUE' 62 'OPENUSB_CB_TERMINATE' 63 'OPENUSB_IO_STALL' 64 'OPENUSB_IO_CRC_ERROR' 65 'OPENUSB_IO_DEVICE_HUNG' 66 'OPENUSB_IO_REQ_TOO_BIG' 67 'OPENUSB_IO_BIT_STUFFING' 68 'OPENUSB_IO_UNEXPECTED_PID' 69 'OPENUSB_IO_DATA_OVERRUN' 70 'OPENUSB_IO_DATA_UNDERRUN' 71 'OPENUSB_IO_BUFFER_OVERRUN' 72 'OPENUSB_IO_BUFFER_UNDERRUN' 73 'OPENUSB_IO_PID_CHECK_FAILURE' 74 'OPENUSB_IO_DATA_TOGGLE_MISMATCH' 75 'OPENUSB_IO_TIMEOUT' 76 'OPENUSB_IO_CANCELED' 77 ] 78 79_logger = logging.getLogger('usb.backend.openusb') 80 81OPENUSB_SUCCESS = 0 82OPENUSB_PLATFORM_FAILURE = -1 83OPENUSB_NO_RESOURCES = -2 84OPENUSB_NO_BANDWIDTH = -3 85OPENUSB_NOT_SUPPORTED = -4 86OPENUSB_HC_HARDWARE_ERROR = -5 87OPENUSB_INVALID_PERM = -6 88OPENUSB_BUSY = -7 89OPENUSB_BADARG = -8 90OPENUSB_NOACCESS = -9 91OPENUSB_PARSE_ERROR = -10 92OPENUSB_UNKNOWN_DEVICE = -11 93OPENUSB_INVALID_HANDLE = -12 94OPENUSB_SYS_FUNC_FAILURE = -13 95OPENUSB_NULL_LIST = -14 96OPENUSB_CB_CONTINUE = -20 97OPENUSB_CB_TERMINATE = -21 98OPENUSB_IO_STALL = -50 99OPENUSB_IO_CRC_ERROR = -51 100OPENUSB_IO_DEVICE_HUNG = -52 101OPENUSB_IO_REQ_TOO_BIG = -53 102OPENUSB_IO_BIT_STUFFING = -54 103OPENUSB_IO_UNEXPECTED_PID = -55 104OPENUSB_IO_DATA_OVERRUN = -56 105OPENUSB_IO_DATA_UNDERRUN = -57 106OPENUSB_IO_BUFFER_OVERRUN = -58 107OPENUSB_IO_BUFFER_UNDERRUN = -59 108OPENUSB_IO_PID_CHECK_FAILURE = -60 109OPENUSB_IO_DATA_TOGGLE_MISMATCH = -61 110OPENUSB_IO_TIMEOUT = -62 111OPENUSB_IO_CANCELED = -63 112 113_openusb_errno = { 114 OPENUSB_SUCCESS:None, 115 OPENUSB_PLATFORM_FAILURE:None, 116 OPENUSB_NO_RESOURCES:errno.__dict__.get('ENOMEM', None), 117 OPENUSB_NO_BANDWIDTH:None, 118 OPENUSB_NOT_SUPPORTED:errno.__dict__.get('ENOSYS', None), 119 OPENUSB_HC_HARDWARE_ERROR:errno.__dict__.get('EIO', None), 120 OPENUSB_INVALID_PERM:errno.__dict__.get('EBADF', None), 121 OPENUSB_BUSY:errno.__dict__.get('EBUSY', None), 122 OPENUSB_BADARG:errno.__dict__.get('EINVAL', None), 123 OPENUSB_NOACCESS:errno.__dict__.get('EACCES', None), 124 OPENUSB_PARSE_ERROR:None, 125 OPENUSB_UNKNOWN_DEVICE:errno.__dict__.get('ENODEV', None), 126 OPENUSB_INVALID_HANDLE:errno.__dict__.get('EINVAL', None), 127 OPENUSB_SYS_FUNC_FAILURE:None, 128 OPENUSB_NULL_LIST:None, 129 OPENUSB_CB_CONTINUE:None, 130 OPENUSB_CB_TERMINATE:None, 131 OPENUSB_IO_STALL:errno.__dict__.get('EIO', None), 132 OPENUSB_IO_CRC_ERROR:errno.__dict__.get('EIO', None), 133 OPENUSB_IO_DEVICE_HUNG:errno.__dict__.get('EIO', None), 134 OPENUSB_IO_REQ_TOO_BIG:errno.__dict__.get('E2BIG', None), 135 OPENUSB_IO_BIT_STUFFING:None, 136 OPENUSB_IO_UNEXPECTED_PID:errno.__dict__.get('ESRCH', None), 137 OPENUSB_IO_DATA_OVERRUN:errno.__dict__.get('EOVERFLOW', None), 138 OPENUSB_IO_DATA_UNDERRUN:None, 139 OPENUSB_IO_BUFFER_OVERRUN:errno.__dict__.get('EOVERFLOW', None), 140 OPENUSB_IO_BUFFER_UNDERRUN:None, 141 OPENUSB_IO_PID_CHECK_FAILURE:None, 142 OPENUSB_IO_DATA_TOGGLE_MISMATCH:None, 143 OPENUSB_IO_TIMEOUT:errno.__dict__.get('ETIMEDOUT', None), 144 OPENUSB_IO_CANCELED:errno.__dict__.get('EINTR', None) 145} 146 147class _usb_endpoint_desc(Structure): 148 _fields_ = [('bLength', c_uint8), 149 ('bDescriptorType', c_uint8), 150 ('bEndpointAddress', c_uint8), 151 ('bmAttributes', c_uint8), 152 ('wMaxPacketSize', c_uint16), 153 ('bInterval', c_uint8), 154 ('bRefresh', c_uint8), 155 ('bSynchAddress', c_uint8)] 156 157class _usb_interface_desc(Structure): 158 _fields_ = [('bLength', c_uint8), 159 ('bDescriptorType', c_uint8), 160 ('bInterfaceNumber', c_uint8), 161 ('bAlternateSetting', c_uint8), 162 ('bNumEndpoints', c_uint8), 163 ('bInterfaceClass', c_uint8), 164 ('bInterfaceSubClass', c_uint8), 165 ('bInterfaceProtocol', c_uint8), 166 ('iInterface', c_uint8)] 167 168class _usb_config_desc(Structure): 169 _fields_ = [('bLength', c_uint8), 170 ('bDescriptorType', c_uint8), 171 ('wTotalLength', c_uint16), 172 ('bNumInterfaces', c_uint8), 173 ('bConfigurationValue', c_uint8), 174 ('iConfiguration', c_uint8), 175 ('bmAttributes', c_uint8), 176 ('bMaxPower', c_uint8)] 177 178class _usb_device_desc(Structure): 179 _fields_ = [('bLength', c_uint8), 180 ('bDescriptorType', c_uint8), 181 ('bcdUSB', c_uint16), 182 ('bDeviceClass', c_uint8), 183 ('bDeviceSubClass', c_uint8), 184 ('bDeviceProtocol', c_uint8), 185 ('bMaxPacketSize0', c_uint8), 186 ('idVendor', c_uint16), 187 ('idProduct', c_uint16), 188 ('bcdDevice', c_uint16), 189 ('iManufacturer', c_uint8), 190 ('iProduct', c_uint8), 191 ('iSerialNumber', c_uint8), 192 ('bNumConfigurations', c_uint8)] 193 194class _openusb_request_result(Structure): 195 _fields_ = [('status', c_int32), 196 ('transferred_bytes', c_uint32)] 197 198class _openusb_ctrl_request(Structure): 199 def __init__(self): 200 super(_openusb_ctrl_request, self).__init__() 201 self.setup.bmRequestType = 0 202 self.setup.bRequest = 0 203 self.setup.wValue = 0 204 self.setup.wIndex = 0 205 self.payload = None 206 self.length = 0 207 self.timeout = 0 208 self.flags = 0 209 self.result.status = 0 210 self.result.transferred_bytes = 0 211 self.next = None 212 213 class _openusb_ctrl_setup(Structure): 214 _fields_ = [('bmRequestType', c_uint8), 215 ('bRequest', c_uint8), 216 ('wValue', c_uint16), 217 ('wIndex', c_uint16)] 218 _fields_ = [('setup', _openusb_ctrl_setup), 219 ('payload', POINTER(c_uint8)), 220 ('length', c_uint32), 221 ('timeout', c_uint32), 222 ('flags', c_uint32), 223 ('result', _openusb_request_result), 224 ('next', c_void_p)] 225 226class _openusb_intr_request(Structure): 227 _fields_ = [('interval', c_uint16), 228 ('payload', POINTER(c_uint8)), 229 ('length', c_uint32), 230 ('timeout', c_uint32), 231 ('flags', c_uint32), 232 ('result', _openusb_request_result), 233 ('next', c_void_p)] 234 235class _openusb_bulk_request(Structure): 236 _fields_ = [('payload', POINTER(c_uint8)), 237 ('length', c_uint32), 238 ('timeout', c_uint32), 239 ('flags', c_uint32), 240 ('result', _openusb_request_result), 241 ('next', c_void_p)] 242 243class _openusb_isoc_pkts(Structure): 244 class _openusb_isoc_packet(Structure): 245 _fields_ = [('payload', POINTER(c_uint8)), 246 ('length', c_uint32)] 247 _fields_ = [('num_packets', c_uint32), 248 ('packets', POINTER(_openusb_isoc_packet))] 249 250class _openusb_isoc_request(Structure): 251 _fields_ = [('start_frame', c_uint32), 252 ('flags', c_uint32), 253 ('pkts', _openusb_isoc_pkts), 254 ('isoc_results', POINTER(_openusb_request_result)), 255 ('isoc_status', c_int32), 256 ('next', c_void_p)] 257 258_openusb_devid = c_uint64 259_openusb_busid = c_uint64 260_openusb_handle = c_uint64 261_openusb_dev_handle = c_uint64 262 263_lib = None 264_ctx = None 265 266def _load_library(find_library=None): 267 # FIXME: cygwin name is "openusb"? 268 # (that's what the original _load_library() function 269 # would have searched for) 270 return usb.libloader.load_locate_library( 271 ('openusb',), 'openusb', "OpenUSB library", find_library=find_library 272 ) 273 274def _setup_prototypes(lib): 275 # int32_t openusb_init(uint32_t flags , openusb_handle_t *handle); 276 lib.openusb_init.argtypes = [c_uint32, POINTER(_openusb_handle)] 277 lib.openusb_init.restype = c_int32 278 279 # void openusb_fini(openusb_handle_t handle ); 280 lib.openusb_fini.argtypes = [_openusb_handle] 281 282 # uint32_t openusb_get_busid_list(openusb_handle_t handle, 283 # openusb_busid_t **busids, 284 # uint32_t *num_busids); 285 lib.openusb_get_busid_list.argtypes = [ 286 _openusb_handle, 287 POINTER(POINTER(_openusb_busid)), 288 POINTER(c_uint32) 289 ] 290 291 # void openusb_free_busid_list(openusb_busid_t * busids); 292 lib.openusb_free_busid_list.argtypes = [POINTER(_openusb_busid)] 293 294 # uint32_t openusb_get_devids_by_bus(openusb_handle_t handle, 295 # openusb_busid_t busid, 296 # openusb_devid_t **devids, 297 # uint32_t *num_devids); 298 lib.openusb_get_devids_by_bus.argtypes = [ 299 _openusb_handle, 300 _openusb_busid, 301 POINTER(POINTER(_openusb_devid)), 302 POINTER(c_uint32) 303 ] 304 305 lib.openusb_get_devids_by_bus.restype = c_int32 306 307 # void openusb_free_devid_list(openusb_devid_t * devids); 308 lib.openusb_free_devid_list.argtypes = [POINTER(_openusb_devid)] 309 310 # int32_t openusb_open_device(openusb_handle_t handle, 311 # openusb_devid_t devid , 312 # uint32_t flags, 313 # openusb_dev_handle_t *dev); 314 lib.openusb_open_device.argtypes = [ 315 _openusb_handle, 316 _openusb_devid, 317 c_uint32, 318 POINTER(_openusb_dev_handle) 319 ] 320 321 lib.openusb_open_device.restype = c_int32 322 323 # int32_t openusb_close_device(openusb_dev_handle_t dev); 324 lib.openusb_close_device.argtypes = [_openusb_dev_handle] 325 lib.openusb_close_device.restype = c_int32 326 327 # int32_t openusb_set_configuration(openusb_dev_handle_t dev, 328 # uint8_t cfg); 329 lib.openusb_set_configuration.argtypes = [_openusb_dev_handle, c_uint8] 330 lib.openusb_set_configuration.restype = c_int32 331 332 # int32_t openusb_get_configuration(openusb_dev_handle_t dev, 333 # uint8_t *cfg); 334 lib.openusb_get_configuration.argtypes = [_openusb_dev_handle, POINTER(c_uint8)] 335 lib.openusb_get_configuration.restype = c_int32 336 337 # int32_t openusb_claim_interface(openusb_dev_handle_t dev, 338 # uint8_t ifc, 339 # openusb_init_flag_t flags); 340 lib.openusb_claim_interface.argtypes = [ 341 _openusb_dev_handle, 342 c_uint8, 343 c_int 344 ] 345 346 lib.openusb_claim_interface.restype = c_int32 347 348 # int32_t openusb_release_interface(openusb_dev_handle_t dev, 349 # uint8_t ifc); 350 lib.openusb_release_interface.argtypes = [ 351 _openusb_dev_handle, 352 c_uint8 353 ] 354 355 lib.openusb_release_interface.restype = c_int32 356 357 # int32_topenusb_set_altsetting(openusb_dev_handle_t dev, 358 # uint8_t ifc, 359 # uint8_t alt); 360 lib.openusb_set_altsetting.argtypes = [ 361 _openusb_dev_handle, 362 c_uint8, 363 c_uint8 364 ] 365 lib.openusb_set_altsetting.restype = c_int32 366 367 # int32_t openusb_reset(openusb_dev_handle_t dev); 368 lib.openusb_reset.argtypes = [_openusb_dev_handle] 369 lib.openusb_reset.restype = c_int32 370 371 # int32_t openusb_parse_device_desc(openusb_handle_t handle, 372 # openusb_devid_t devid, 373 # uint8_t *buffer, 374 # uint16_t buflen, 375 # usb_device_desc_t *devdesc); 376 lib.openusb_parse_device_desc.argtypes = [ 377 _openusb_handle, 378 _openusb_devid, 379 POINTER(c_uint8), 380 c_uint16, 381 POINTER(_usb_device_desc) 382 ] 383 384 lib.openusb_parse_device_desc.restype = c_int32 385 386 # int32_t openusb_parse_config_desc(openusb_handle_t handle, 387 # openusb_devid_t devid, 388 # uint8_t *buffer, 389 # uint16_t buflen, 390 # uint8_t cfgidx, 391 # usb_config_desc_t *cfgdesc); 392 lib.openusb_parse_config_desc.argtypes = [ 393 _openusb_handle, 394 _openusb_devid, 395 POINTER(c_uint8), 396 c_uint16, 397 c_uint8, 398 POINTER(_usb_config_desc) 399 ] 400 lib.openusb_parse_config_desc.restype = c_int32 401 402 # int32_t openusb_parse_interface_desc(openusb_handle_t handle, 403 # openusb_devid_t devid, 404 # uint8_t *buffer, 405 # uint16_t buflen, 406 # uint8_t cfgidx, 407 # uint8_t ifcidx, 408 # uint8_t alt, 409 # usb_interface_desc_t *ifcdesc); 410 lib.openusb_parse_interface_desc.argtypes = [ 411 _openusb_handle, 412 _openusb_devid, 413 POINTER(c_uint8), 414 c_uint16, 415 c_uint8, 416 c_uint8, 417 c_uint8, 418 POINTER(_usb_interface_desc) 419 ] 420 421 lib.openusb_parse_interface_desc.restype = c_int32 422 423 # int32_t openusb_parse_endpoint_desc(openusb_handle_t handle, 424 # openusb_devid_t devid, 425 # uint8_t *buffer, 426 # uint16_t buflen, 427 # uint8_t cfgidx, 428 # uint8_t ifcidx, 429 # uint8_t alt, 430 # uint8_t eptidx, 431 # usb_endpoint_desc_t *eptdesc); 432 lib.openusb_parse_endpoint_desc.argtypes = [ 433 _openusb_handle, 434 _openusb_devid, 435 POINTER(c_uint8), 436 c_uint16, 437 c_uint8, 438 c_uint8, 439 c_uint8, 440 c_uint8, 441 POINTER(_usb_endpoint_desc) 442 ] 443 444 lib.openusb_parse_interface_desc.restype = c_int32 445 446 # const char *openusb_strerror(int32_t error ); 447 lib.openusb_strerror.argtypes = [c_int32] 448 lib.openusb_strerror.restype = c_char_p 449 450 # int32_t openusb_ctrl_xfer(openusb_dev_handle_t dev, 451 # uint8_t ifc, 452 # uint8_t ept, 453 # openusb_ctrl_request_t *ctrl); 454 lib.openusb_ctrl_xfer.argtypes = [ 455 _openusb_dev_handle, 456 c_uint8, 457 c_uint8, 458 POINTER(_openusb_ctrl_request) 459 ] 460 461 lib.openusb_ctrl_xfer.restype = c_int32 462 463 # int32_t openusb_intr_xfer(openusb_dev_handle_t dev, 464 # uint8_t ifc, 465 # uint8_t ept, 466 # openusb_intr_request_t *intr); 467 lib.openusb_intr_xfer.argtypes = [ 468 _openusb_dev_handle, 469 c_uint8, 470 c_uint8, 471 POINTER(_openusb_intr_request) 472 ] 473 474 lib.openusb_bulk_xfer.restype = c_int32 475 476 # int32_t openusb_bulk_xfer(openusb_dev_handle_t dev, 477 # uint8_t ifc, 478 # uint8_t ept, 479 # openusb_bulk_request_t *bulk); 480 lib.openusb_bulk_xfer.argtypes = [ 481 _openusb_dev_handle, 482 c_uint8, 483 c_uint8, 484 POINTER(_openusb_bulk_request) 485 ] 486 487 lib.openusb_bulk_xfer.restype = c_int32 488 489 # int32_t openusb_isoc_xfer(openusb_dev_handle_t dev, 490 # uint8_t ifc, 491 # uint8_t ept, 492 # openusb_isoc_request_t *isoc); 493 lib.openusb_isoc_xfer.argtypes = [ 494 _openusb_dev_handle, 495 c_uint8, 496 c_uint8, 497 POINTER(_openusb_isoc_request) 498 ] 499 500 lib.openusb_isoc_xfer.restype = c_int32 501 502def _check(ret): 503 if hasattr(ret, 'value'): 504 ret = ret.value 505 506 if ret != 0: 507 raise USBError(_lib.openusb_strerror(ret), ret, _openusb_errno[ret]) 508 return ret 509 510class _Context(_objfinalizer.AutoFinalizedObject): 511 def __init__(self): 512 self.handle = _openusb_handle() 513 _check(_lib.openusb_init(0, byref(self.handle))) 514 def _finalize_object(self): 515 _lib.openusb_fini(self.handle) 516 517class _BusIterator(_objfinalizer.AutoFinalizedObject): 518 def __init__(self): 519 self.buslist = POINTER(_openusb_busid)() 520 num_busids = c_uint32() 521 _check(_lib.openusb_get_busid_list(_ctx.handle, 522 byref(self.buslist), 523 byref(num_busids))) 524 self.num_busids = num_busids.value 525 def __iter__(self): 526 for i in range(self.num_busids): 527 yield self.buslist[i] 528 def _finalize_object(self): 529 _lib.openusb_free_busid_list(self.buslist) 530 531class _DevIterator(_objfinalizer.AutoFinalizedObject): 532 def __init__(self, busid): 533 self.devlist = POINTER(_openusb_devid)() 534 num_devids = c_uint32() 535 _check(_lib.openusb_get_devids_by_bus(_ctx.handle, 536 busid, 537 byref(self.devlist), 538 byref(num_devids))) 539 self.num_devids = num_devids.value 540 def __iter__(self): 541 for i in range(self.num_devids): 542 yield self.devlist[i] 543 def _finalize_object(self): 544 _lib.openusb_free_devid_list(self.devlist) 545 546class _OpenUSB(usb.backend.IBackend): 547 @methodtrace(_logger) 548 def enumerate_devices(self): 549 for bus in _BusIterator(): 550 for devid in _DevIterator(bus): 551 yield devid 552 553 @methodtrace(_logger) 554 def get_device_descriptor(self, dev): 555 desc = _usb_device_desc() 556 _check(_lib.openusb_parse_device_desc(_ctx.handle, 557 dev, 558 None, 559 0, 560 byref(desc))) 561 desc.bus = None 562 desc.address = None 563 desc.port_number = None 564 desc.port_numbers = None 565 desc.speed = None 566 return desc 567 568 @methodtrace(_logger) 569 def get_configuration_descriptor(self, dev, config): 570 desc = _usb_config_desc() 571 _check(_lib.openusb_parse_config_desc(_ctx.handle, 572 dev, 573 None, 574 0, 575 config, 576 byref(desc))) 577 desc.extra_descriptors = None 578 return desc 579 580 @methodtrace(_logger) 581 def get_interface_descriptor(self, dev, intf, alt, config): 582 desc = _usb_interface_desc() 583 _check(_lib.openusb_parse_interface_desc(_ctx.handle, 584 dev, 585 None, 586 0, 587 config, 588 intf, 589 alt, 590 byref(desc))) 591 desc.extra_descriptors = None 592 return desc 593 594 @methodtrace(_logger) 595 def get_endpoint_descriptor(self, dev, ep, intf, alt, config): 596 desc = _usb_endpoint_desc() 597 _check(_lib.openusb_parse_endpoint_desc(_ctx.handle, 598 dev, 599 None, 600 0, 601 config, 602 intf, 603 alt, 604 ep, 605 byref(desc))) 606 desc.extra_descriptors = None 607 return desc 608 609 @methodtrace(_logger) 610 def open_device(self, dev): 611 handle = _openusb_dev_handle() 612 _check(_lib.openusb_open_device(_ctx.handle, dev, 0, byref(handle))) 613 return handle 614 615 @methodtrace(_logger) 616 def close_device(self, dev_handle): 617 _lib.openusb_close_device(dev_handle) 618 619 @methodtrace(_logger) 620 def set_configuration(self, dev_handle, config_value): 621 _check(_lib.openusb_set_configuration(dev_handle, config_value)) 622 623 @methodtrace(_logger) 624 def get_configuration(self, dev_handle): 625 config = c_uint8() 626 _check(_lib.openusb_get_configuration(dev_handle, byref(config))) 627 return config.value 628 629 @methodtrace(_logger) 630 def set_interface_altsetting(self, dev_handle, intf, altsetting): 631 _check(_lib.openusb_set_altsetting(dev_handle, intf, altsetting)) 632 633 @methodtrace(_logger) 634 def claim_interface(self, dev_handle, intf): 635 _check(_lib.openusb_claim_interface(dev_handle, intf, 0)) 636 637 @methodtrace(_logger) 638 def release_interface(self, dev_handle, intf): 639 _lib.openusb_release_interface(dev_handle, intf) 640 641 @methodtrace(_logger) 642 def bulk_write(self, dev_handle, ep, intf, data, timeout): 643 request = _openusb_bulk_request() 644 memset(byref(request), 0, sizeof(request)) 645 payload, request.length = data.buffer_info() 646 request.payload = cast(payload, POINTER(c_uint8)) 647 request.timeout = timeout 648 _check(_lib.openusb_bulk_xfer(dev_handle, intf, ep, byref(request))) 649 return request.result.transferred_bytes 650 651 @methodtrace(_logger) 652 def bulk_read(self, dev_handle, ep, intf, buff, timeout): 653 request = _openusb_bulk_request() 654 memset(byref(request), 0, sizeof(request)) 655 payload, request.length = buff.buffer_info() 656 request.payload = cast(payload, POINTER(c_uint8)) 657 request.timeout = timeout 658 _check(_lib.openusb_bulk_xfer(dev_handle, intf, ep, byref(request))) 659 return request.result.transferred_bytes 660 661 @methodtrace(_logger) 662 def intr_write(self, dev_handle, ep, intf, data, timeout): 663 request = _openusb_intr_request() 664 memset(byref(request), 0, sizeof(request)) 665 payload, request.length = data.buffer_info() 666 request.payload = cast(payload, POINTER(c_uint8)) 667 request.timeout = timeout 668 _check(_lib.openusb_intr_xfer(dev_handle, intf, ep, byref(request))) 669 return request.result.transferred_bytes 670 671 @methodtrace(_logger) 672 def intr_read(self, dev_handle, ep, intf, buff, timeout): 673 request = _openusb_intr_request() 674 memset(byref(request), 0, sizeof(request)) 675 payload, request.length = buff.buffer_info() 676 request.payload = cast(payload, POINTER(c_uint8)) 677 request.timeout = timeout 678 _check(_lib.openusb_intr_xfer(dev_handle, intf, ep, byref(request))) 679 return request.result.transferred_bytes 680 681# TODO: implement isochronous 682# @methodtrace(_logger) 683# def iso_write(self, dev_handle, ep, intf, data, timeout): 684# pass 685 686# @methodtrace(_logger) 687# def iso_read(self, dev_handle, ep, intf, size, timeout): 688# pass 689 690 @methodtrace(_logger) 691 def ctrl_transfer(self, 692 dev_handle, 693 bmRequestType, 694 bRequest, 695 wValue, 696 wIndex, 697 data, 698 timeout): 699 request = _openusb_ctrl_request() 700 request.setup.bmRequestType = bmRequestType 701 request.setup.bRequest = bRequest 702 request.setup.wValue 703 request.setup.wIndex 704 request.timeout = timeout 705 706 direction = usb.util.ctrl_direction(bmRequestType) 707 708 payload, request.length = data.buffer_info() 709 request.length *= data.itemsize 710 request.payload = cast(payload, POINTER(c_uint8)) 711 712 _check(_lib.openusb_ctrl_xfer(dev_handle, 0, 0, byref(request))) 713 714 return request.result.transferred_bytes 715 716 @methodtrace(_logger) 717 def reset_device(self, dev_handle): 718 _check(_lib.openusb_reset(dev_handle)) 719 720 @methodtrace(_logger) 721 def clear_halt(self, dev_handle, ep): 722 bmRequestType = util.build_request_type( 723 util.CTRL_OUT, 724 util.CTRL_TYPE_STANDARD, 725 util.CTRL_RECIPIENT_ENDPOINT) 726 self.ctrl_transfer( 727 dev_handle, 728 bmRequestType, 729 0x03, 730 0, 731 ep, 732 _interop.as_array(), 733 1000) 734 735def get_backend(find_library=None): 736 try: 737 global _lib, _ctx 738 if _lib is None: 739 _lib = _load_library(find_library) 740 _setup_prototypes(_lib) 741 _ctx = _Context() 742 return _OpenUSB() 743 except usb.libloader.LibraryException: 744 # exception already logged (if any) 745 _logger.error('Error loading OpenUSB backend', exc_info=False) 746 return None 747 except Exception: 748 _logger.error('Error loading OpenUSB backend', exc_info=True) 749 return None 750