libusb01.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. # Copyright (C) 2009-2011 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. from ctypes import *
  29. import ctypes.util
  30. import os
  31. import usb.backend
  32. import usb.util
  33. import sys
  34. from usb.core import USBError
  35. from usb._debug import methodtrace
  36. import usb._interop as _interop
  37. import logging
  38. __author__ = 'Wander Lairson Costa'
  39. __all__ = ['get_backend']
  40. _logger = logging.getLogger('usb.backend.libusb01')
  41. # usb.h
  42. _PC_PATH_MAX = 4
  43. if sys.platform != 'win32':
  44. _PATH_MAX = os.pathconf('.', _PC_PATH_MAX)
  45. else:
  46. _PATH_MAX = 511
  47. # libusb-win32 makes all structures packed, while
  48. # default libusb only does for some structures
  49. # _PackPolicy defines the structure packing according
  50. # to the platform.
  51. class _PackPolicy(object):
  52. pass
  53. if sys.platform == 'win32':
  54. _PackPolicy._pack_ = 1
  55. # Data structures
  56. class _usb_descriptor_header(Structure):
  57. _pack_ = 1
  58. _fields_ = [('blength', c_uint8),
  59. ('bDescriptorType', c_uint8)]
  60. class _usb_string_descriptor(Structure):
  61. _pack_ = 1
  62. _fields_ = [('bLength', c_uint8),
  63. ('bDescriptorType', c_uint8),
  64. ('wData', c_uint16)]
  65. class _usb_endpoint_descriptor(Structure, _PackPolicy):
  66. _fields_ = [('bLength', c_uint8),
  67. ('bDescriptorType', c_uint8),
  68. ('bEndpointAddress', c_uint8),
  69. ('bmAttributes', c_uint8),
  70. ('wMaxPacketSize', c_uint16),
  71. ('bInterval', c_uint8),
  72. ('bRefresh', c_uint8),
  73. ('bSynchAddress', c_uint8),
  74. ('extra', POINTER(c_uint8)),
  75. ('extralen', c_int)]
  76. class _usb_interface_descriptor(Structure, _PackPolicy):
  77. _fields_ = [('bLength', c_uint8),
  78. ('bDescriptorType', c_uint8),
  79. ('bInterfaceNumber', c_uint8),
  80. ('bAlternateSetting', c_uint8),
  81. ('bNumEndpoints', c_uint8),
  82. ('bInterfaceClass', c_uint8),
  83. ('bInterfaceSubClass', c_uint8),
  84. ('bInterfaceProtocol', c_uint8),
  85. ('iInterface', c_uint8),
  86. ('endpoint', POINTER(_usb_endpoint_descriptor)),
  87. ('extra', POINTER(c_uint8)),
  88. ('extralen', c_int)]
  89. class _usb_interface(Structure, _PackPolicy):
  90. _fields_ = [('altsetting', POINTER(_usb_interface_descriptor)),
  91. ('num_altsetting', c_int)]
  92. class _usb_config_descriptor(Structure, _PackPolicy):
  93. _fields_ = [('bLength', c_uint8),
  94. ('bDescriptorType', c_uint8),
  95. ('wTotalLength', c_uint16),
  96. ('bNumInterfaces', c_uint8),
  97. ('bConfigurationValue', c_uint8),
  98. ('iConfiguration', c_uint8),
  99. ('bmAttributes', c_uint8),
  100. ('bMaxPower', c_uint8),
  101. ('interface', POINTER(_usb_interface)),
  102. ('extra', POINTER(c_uint8)),
  103. ('extralen', c_int)]
  104. class _usb_device_descriptor(Structure, _PackPolicy):
  105. _pack_ = 1
  106. _fields_ = [('bLength', c_uint8),
  107. ('bDescriptorType', c_uint8),
  108. ('bcdUSB', c_uint16),
  109. ('bDeviceClass', c_uint8),
  110. ('bDeviceSubClass', c_uint8),
  111. ('bDeviceProtocol', c_uint8),
  112. ('bMaxPacketSize0', c_uint8),
  113. ('idVendor', c_uint16),
  114. ('idProduct', c_uint16),
  115. ('bcdDevice', c_uint16),
  116. ('iManufacturer', c_uint8),
  117. ('iProduct', c_uint8),
  118. ('iSerialNumber', c_uint8),
  119. ('bNumConfigurations', c_uint8)]
  120. class _usb_device(Structure, _PackPolicy):
  121. pass
  122. class _usb_bus(Structure, _PackPolicy):
  123. pass
  124. _usb_device._fields_ = [('next', POINTER(_usb_device)),
  125. ('prev', POINTER(_usb_device)),
  126. ('filename', c_int8 * (_PATH_MAX + 1)),
  127. ('bus', POINTER(_usb_bus)),
  128. ('descriptor', _usb_device_descriptor),
  129. ('config', POINTER(_usb_config_descriptor)),
  130. ('dev', c_void_p),
  131. ('devnum', c_uint8),
  132. ('num_children', c_ubyte),
  133. ('children', POINTER(POINTER(_usb_device)))]
  134. _usb_bus._fields_ = [('next', POINTER(_usb_bus)),
  135. ('prev', POINTER(_usb_bus)),
  136. ('dirname', c_char * (_PATH_MAX + 1)),
  137. ('devices', POINTER(_usb_device)),
  138. ('location', c_uint32),
  139. ('root_dev', POINTER(_usb_device))]
  140. _usb_dev_handle = c_void_p
  141. _lib = None
  142. def _load_library():
  143. candidates = ('usb-0.1', 'usb', 'libusb0')
  144. for candidate in candidates:
  145. libname = ctypes.util.find_library(candidate)
  146. if libname is not None: break
  147. else:
  148. # corner cases
  149. # cygwin predefines library names with 'cyg' instead of 'lib'
  150. if sys.platform == 'cygwin':
  151. try:
  152. return CDLL('cygusb0.dll')
  153. except:
  154. _logger.error('Libusb 0 could not be loaded in cygwin', exc_info=True)
  155. raise OSError('USB library could not be found')
  156. return CDLL(libname)
  157. def _setup_prototypes(lib):
  158. # usb_dev_handle *usb_open(struct usb_device *dev);
  159. lib.usb_open.argtypes = [POINTER(_usb_device)]
  160. lib.usb_open.restype = _usb_dev_handle
  161. # int usb_close(usb_dev_handle *dev);
  162. lib.usb_close.argtypes = [_usb_dev_handle]
  163. # int usb_get_string(usb_dev_handle *dev,
  164. # int index,
  165. # int langid,
  166. # char *buf,
  167. # size_t buflen);
  168. lib.usb_get_string.argtypes = [
  169. _usb_dev_handle,
  170. c_int,
  171. c_int,
  172. c_char_p,
  173. c_size_t
  174. ]
  175. # int usb_get_string_simple(usb_dev_handle *dev,
  176. # int index,
  177. # char *buf,
  178. # size_t buflen);
  179. lib.usb_get_string_simple.argtypes = [
  180. _usb_dev_handle,
  181. c_int,
  182. c_char_p,
  183. c_size_t
  184. ]
  185. # int usb_get_descriptor_by_endpoint(usb_dev_handle *udev,
  186. # int ep,
  187. # unsigned char type,
  188. # unsigned char index,
  189. # void *buf,
  190. # int size);
  191. lib.usb_get_descriptor_by_endpoint.argtypes = [
  192. _usb_dev_handle,
  193. c_int,
  194. c_ubyte,
  195. c_ubyte,
  196. c_void_p,
  197. c_int
  198. ]
  199. # int usb_get_descriptor(usb_dev_handle *udev,
  200. # unsigned char type,
  201. # unsigned char index,
  202. # void *buf,
  203. # int size);
  204. lib.usb_get_descriptor.argtypes = [
  205. _usb_dev_handle,
  206. c_ubyte,
  207. c_ubyte,
  208. c_void_p,
  209. c_int
  210. ]
  211. # int usb_bulk_write(usb_dev_handle *dev,
  212. # int ep,
  213. # const char *bytes,
  214. # int size,
  215. # int timeout);
  216. lib.usb_bulk_write.argtypes = [
  217. _usb_dev_handle,
  218. c_int,
  219. c_char_p,
  220. c_int,
  221. c_int
  222. ]
  223. # int usb_bulk_read(usb_dev_handle *dev,
  224. # int ep,
  225. # char *bytes,
  226. # int size,
  227. # int timeout);
  228. lib.usb_bulk_read.argtypes = [
  229. _usb_dev_handle,
  230. c_int,
  231. c_char_p,
  232. c_int,
  233. c_int
  234. ]
  235. # int usb_interrupt_write(usb_dev_handle *dev,
  236. # int ep,
  237. # const char *bytes,
  238. # int size,
  239. # int timeout);
  240. lib.usb_interrupt_write.argtypes = [
  241. _usb_dev_handle,
  242. c_int,
  243. c_char_p,
  244. c_int,
  245. c_int
  246. ]
  247. # int usb_interrupt_read(usb_dev_handle *dev,
  248. # int ep,
  249. # char *bytes,
  250. # int size,
  251. # int timeout);
  252. lib.usb_interrupt_read.argtypes = [
  253. _usb_dev_handle,
  254. c_int,
  255. c_char_p,
  256. c_int,
  257. c_int
  258. ]
  259. # int usb_control_msg(usb_dev_handle *dev,
  260. # int requesttype,
  261. # int request,
  262. # int value,
  263. # int index,
  264. # char *bytes,
  265. # int size,
  266. # int timeout);
  267. lib.usb_control_msg.argtypes = [
  268. _usb_dev_handle,
  269. c_int,
  270. c_int,
  271. c_int,
  272. c_int,
  273. c_char_p,
  274. c_int,
  275. c_int
  276. ]
  277. # int usb_set_configuration(usb_dev_handle *dev, int configuration);
  278. lib.usb_set_configuration.argtypes = [_usb_dev_handle, c_int]
  279. # int usb_claim_interface(usb_dev_handle *dev, int interface);
  280. lib.usb_claim_interface.argtypes = [_usb_dev_handle, c_int]
  281. # int usb_release_interface(usb_dev_handle *dev, int interface);
  282. lib.usb_release_interface.argtypes = [_usb_dev_handle, c_int]
  283. # int usb_set_altinterface(usb_dev_handle *dev, int alternate);
  284. lib.usb_set_altinterface.argtypes = [_usb_dev_handle, c_int]
  285. # int usb_resetep(usb_dev_handle *dev, unsigned int ep);
  286. lib.usb_resetep.argtypes = [_usb_dev_handle, c_int]
  287. # int usb_clear_halt(usb_dev_handle *dev, unsigned int ep);
  288. lib.usb_clear_halt.argtypes = [_usb_dev_handle, c_int]
  289. # int usb_reset(usb_dev_handle *dev);
  290. lib.usb_reset.argtypes = [_usb_dev_handle]
  291. # char *usb_strerror(void);
  292. lib.usb_strerror.argtypes = []
  293. lib.usb_strerror.restype = c_char_p
  294. # void usb_set_debug(int level);
  295. lib.usb_set_debug.argtypes = [c_int]
  296. # struct usb_device *usb_device(usb_dev_handle *dev);
  297. lib.usb_device.argtypes = [_usb_dev_handle]
  298. lib.usb_device.restype = POINTER(_usb_device)
  299. # struct usb_bus *usb_get_busses(void);
  300. lib.usb_get_busses.restype = POINTER(_usb_bus)
  301. def _check(retval):
  302. if retval is None:
  303. errmsg = _lib.usb_strerror()
  304. else:
  305. ret = int(retval)
  306. if ret < 0:
  307. errmsg = _lib.usb_strerror()
  308. # No error means that we need to get the error
  309. # message from the return code
  310. # Thanks to Nicholas Wheeler to point out the problem...
  311. # Also see issue #2860940
  312. if errmsg.lower() == 'no error':
  313. errmsg = os.strerror(-ret)
  314. else:
  315. return ret
  316. raise USBError(errmsg)
  317. # implementation of libusb 0.1.x backend
  318. class _LibUSB(usb.backend.IBackend):
  319. @methodtrace(_logger)
  320. def enumerate_devices(self):
  321. _check(_lib.usb_find_busses())
  322. _check(_lib.usb_find_devices())
  323. bus = _lib.usb_get_busses()
  324. while bool(bus):
  325. dev = bus[0].devices
  326. while bool(dev):
  327. yield dev[0]
  328. dev = dev[0].next
  329. bus = bus[0].next
  330. @methodtrace(_logger)
  331. def get_device_descriptor(self, dev):
  332. return dev.descriptor
  333. @methodtrace(_logger)
  334. def get_configuration_descriptor(self, dev, config):
  335. if config >= dev.descriptor.bNumConfigurations:
  336. raise IndexError('Invalid configuration index ' + str(config))
  337. return dev.config[config]
  338. @methodtrace(_logger)
  339. def get_interface_descriptor(self, dev, intf, alt, config):
  340. cfgdesc = self.get_configuration_descriptor(dev, config)
  341. if intf >= cfgdesc.bNumInterfaces:
  342. raise IndexError('Invalid interface index ' + str(interface))
  343. interface = cfgdesc.interface[intf]
  344. if alt >= interface.num_altsetting:
  345. raise IndexError('Invalid alternate setting index ' + str(alt))
  346. return interface.altsetting[alt]
  347. @methodtrace(_logger)
  348. def get_endpoint_descriptor(self, dev, ep, intf, alt, config):
  349. interface = self.get_interface_descriptor(dev, intf, alt, config)
  350. if ep >= interface.bNumEndpoints:
  351. raise IndexError('Invalid endpoint index ' + str(ep))
  352. return interface.endpoint[ep]
  353. @methodtrace(_logger)
  354. def open_device(self, dev):
  355. return _check(_lib.usb_open(dev))
  356. @methodtrace(_logger)
  357. def close_device(self, dev_handle):
  358. _check(_lib.usb_close(dev_handle))
  359. @methodtrace(_logger)
  360. def set_configuration(self, dev_handle, config_value):
  361. _check(_lib.usb_set_configuration(dev_handle, config_value))
  362. @methodtrace(_logger)
  363. def set_interface_altsetting(self, dev_handle, intf, altsetting):
  364. _check(_lib.usb_set_altinterface(dev_handle, altsetting))
  365. @methodtrace(_logger)
  366. def get_configuration(self, dev_handle):
  367. bmRequestType = usb.util.build_request_type(
  368. usb.util.CTRL_IN,
  369. usb.util.CTRL_TYPE_STANDARD,
  370. usb.util.CTRL_RECIPIENT_DEVICE
  371. )
  372. return self.ctrl_transfer(dev_handle,
  373. bmRequestType,
  374. 0x08,
  375. 0,
  376. 0,
  377. 1,
  378. 100
  379. )[0]
  380. @methodtrace(_logger)
  381. def claim_interface(self, dev_handle, intf):
  382. _check(_lib.usb_claim_interface(dev_handle, intf))
  383. @methodtrace(_logger)
  384. def release_interface(self, dev_handle, intf):
  385. _check(_lib.usb_release_interface(dev_handle, intf))
  386. @methodtrace(_logger)
  387. def bulk_write(self, dev_handle, ep, intf, data, timeout):
  388. return self.__write(_lib.usb_bulk_write,
  389. dev_handle,
  390. ep,
  391. intf,
  392. data, timeout)
  393. @methodtrace(_logger)
  394. def bulk_read(self, dev_handle, ep, intf, size, timeout):
  395. return self.__read(_lib.usb_bulk_read,
  396. dev_handle,
  397. ep,
  398. intf,
  399. size,
  400. timeout)
  401. @methodtrace(_logger)
  402. def intr_write(self, dev_handle, ep, intf, data, timeout):
  403. return self.__write(_lib.usb_interrupt_write,
  404. dev_handle,
  405. ep,
  406. intf,
  407. data,
  408. timeout)
  409. @methodtrace(_logger)
  410. def intr_read(self, dev_handle, ep, intf, size, timeout):
  411. return self.__read(_lib.usb_interrupt_read,
  412. dev_handle,
  413. ep,
  414. intf,
  415. size,
  416. timeout)
  417. @methodtrace(_logger)
  418. def ctrl_transfer(self,
  419. dev_handle,
  420. bmRequestType,
  421. bRequest,
  422. wValue,
  423. wIndex,
  424. data_or_wLength,
  425. timeout):
  426. if usb.util.ctrl_direction(bmRequestType) == usb.util.CTRL_OUT:
  427. address, length = data_or_wLength.buffer_info()
  428. length *= data_or_wLength.itemsize
  429. return _check(_lib.usb_control_msg(
  430. dev_handle,
  431. bmRequestType,
  432. bRequest,
  433. wValue,
  434. wIndex,
  435. cast(address, c_char_p),
  436. length,
  437. timeout
  438. ))
  439. else:
  440. data = _interop.as_array((0,) * data_or_wLength)
  441. read = int(_check(_lib.usb_control_msg(
  442. dev_handle,
  443. bmRequestType,
  444. bRequest,
  445. wValue,
  446. wIndex,
  447. cast(data.buffer_info()[0],
  448. c_char_p),
  449. data_or_wLength,
  450. timeout
  451. )))
  452. return data[:read]
  453. @methodtrace(_logger)
  454. def reset_device(self, dev_handle):
  455. _check(_lib.usb_reset(dev_handle))
  456. @methodtrace(_logger)
  457. def detach_kernel_driver(self, dev_handle, intf):
  458. _check(_lib.usb_detach_kernel_driver_np(dev_handle, intf))
  459. def __write(self, fn, dev_handle, ep, intf, data, timeout):
  460. address, length = data.buffer_info()
  461. length *= data.itemsize
  462. return int(_check(fn(
  463. dev_handle,
  464. ep,
  465. cast(address, c_char_p),
  466. length,
  467. timeout
  468. )))
  469. def __read(self, fn, dev_handle, ep, intf, size, timeout):
  470. data = _interop.as_array((0,) * size)
  471. address, length = data.buffer_info()
  472. length *= data.itemsize
  473. ret = int(_check(fn(
  474. dev_handle,
  475. ep,
  476. cast(address, c_char_p),
  477. length,
  478. timeout
  479. )))
  480. return data[:ret]
  481. def get_backend():
  482. global _lib
  483. try:
  484. if _lib is None:
  485. _lib = _load_library()
  486. _setup_prototypes(_lib)
  487. _lib.usb_init()
  488. return _LibUSB()
  489. except Exception:
  490. _logger.error('Error loading libusb 0.1 backend', exc_info=True)
  491. return None