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
29r"""usb.core - Core USB features.
30
31This module exports:
32
33Device - a class representing a USB device.
34Configuration - a class representing a configuration descriptor.
35Interface - a class representing an interface descriptor.
36Endpoint - a class representing an endpoint descriptor.
37find() - a function to find USB devices.
38show_devices() - a function to show the devices present.
39"""
40
41__author__ = 'Wander Lairson Costa'
42
43__all__ = [ 'Device', 'Configuration', 'Interface', 'Endpoint', 'find',
44            'show_devices' ]
45
46import usb.util as util
47import copy
48import operator
49import usb._interop as _interop
50import usb._objfinalizer as _objfinalizer
51import usb._lookup as _lu
52import logging
53import array
54import threading
55import functools
56
57_logger = logging.getLogger('usb.core')
58
59_DEFAULT_TIMEOUT = 1000
60
61def _set_attr(input, output, fields):
62    for f in fields:
63       setattr(output, f, getattr(input, f))
64
65def _try_get_string(dev, index, langid = None, default_str_i0 = "",
66        default_access_error = "Error Accessing String"):
67    """ try to get a string, but return a string no matter what
68    """
69    if index == 0 :
70        string = default_str_i0
71    else:
72        try:
73            if langid is None:
74                string = util.get_string(dev, index)
75            else:
76                string = util.get_string(dev, index, langid)
77        except :
78            string = default_access_error
79    return string
80
81def _try_lookup(table, value, default = ""):
82    """ try to get a string from the lookup table, return "" instead of key
83    error
84    """
85    try:
86        string = table[ value ]
87    except KeyError:
88        string = default
89    return string
90
91class _DescriptorInfo(str):
92    """ this class is used so that when a descriptor is shown on the
93    terminal it is propely formatted """
94    def __repr__(self):
95        return self
96
97def synchronized(f):
98    @functools.wraps(f)
99    def wrapper(self, *args, **kwargs):
100        try:
101            self.lock.acquire()
102            return f(self, *args, **kwargs)
103        finally:
104            self.lock.release()
105    return wrapper
106
107class _ResourceManager(object):
108    def __init__(self, dev, backend):
109        self.backend = backend
110        self._active_cfg_index = None
111        self.dev = dev
112        self.handle = None
113        self._claimed_intf = _interop._set()
114        self._ep_info = {}
115        self.lock = threading.RLock()
116
117    @synchronized
118    def managed_open(self):
119        if self.handle is None:
120            self.handle = self.backend.open_device(self.dev)
121        return self.handle
122
123    @synchronized
124    def managed_close(self):
125        if self.handle is not None:
126            self.backend.close_device(self.handle)
127            self.handle = None
128
129    @synchronized
130    def managed_set_configuration(self, device, config):
131        if config is None:
132            cfg = device[0]
133        elif isinstance(config, Configuration):
134            cfg = config
135        elif config == 0: # unconfigured state
136            class MockConfiguration(object):
137                def __init__(self):
138                    self.index = None
139                    self.bConfigurationValue = 0
140            cfg = MockConfiguration()
141        else:
142            cfg = util.find_descriptor(device, bConfigurationValue=config)
143
144        if cfg is None:
145            raise ValueError("Invalid configuration " + str(config))
146
147        self.managed_open()
148        self.backend.set_configuration(self.handle, cfg.bConfigurationValue)
149
150        # cache the index instead of the object to avoid cyclic references
151        # of the device and Configuration (Device tracks the _ResourceManager,
152        # which tracks the Configuration, which tracks the Device)
153        self._active_cfg_index = cfg.index
154
155        self._ep_info.clear()
156
157    @synchronized
158    def managed_claim_interface(self, device, intf):
159        self.managed_open()
160
161        if isinstance(intf, Interface):
162            i = intf.bInterfaceNumber
163        else:
164            i = intf
165
166        if i not in self._claimed_intf:
167            self.backend.claim_interface(self.handle, i)
168            self._claimed_intf.add(i)
169
170    @synchronized
171    def managed_release_interface(self, device, intf):
172        if intf is None:
173            cfg = self.get_active_configuration(device)
174            i = cfg[(0,0)].bInterfaceNumber
175        elif isinstance(intf, Interface):
176            i = intf.bInterfaceNumber
177        else:
178            i = intf
179
180        if i in self._claimed_intf:
181            try:
182                self.backend.release_interface(self.handle, i)
183            finally:
184                self._claimed_intf.remove(i)
185
186    @synchronized
187    def managed_set_interface(self, device, intf, alt):
188        if isinstance(intf, Interface):
189            i = intf
190        else:
191            cfg = self.get_active_configuration(device)
192            if intf is None:
193                intf = cfg[(0,0)].bInterfaceNumber
194            if alt is not None:
195                i = util.find_descriptor(cfg, bInterfaceNumber=intf, bAlternateSetting=alt)
196            else:
197                i = util.find_descriptor(cfg, bInterfaceNumber=intf)
198
199        self.managed_claim_interface(device, i)
200
201        if alt is None:
202            alt = i.bAlternateSetting
203
204        self.backend.set_interface_altsetting(self.handle, i.bInterfaceNumber, alt)
205
206    @synchronized
207    def setup_request(self, device, endpoint):
208        # we need the endpoint address, but the "endpoint" parameter
209        # can be either the a Endpoint object or the endpoint address itself
210        if isinstance(endpoint, Endpoint):
211            endpoint_address = endpoint.bEndpointAddress
212        else:
213            endpoint_address = endpoint
214
215        intf, ep = self.get_interface_and_endpoint(device, endpoint_address)
216        self.managed_claim_interface(device, intf)
217        return (intf, ep)
218
219    # Find the interface and endpoint objects which endpoint address belongs to
220    @synchronized
221    def get_interface_and_endpoint(self, device, endpoint_address):
222        try:
223            return self._ep_info[endpoint_address]
224        except KeyError:
225            for intf in self.get_active_configuration(device):
226                ep = util.find_descriptor(intf, bEndpointAddress=endpoint_address)
227                if ep is not None:
228                    self._ep_info[endpoint_address] = (intf, ep)
229                    return intf, ep
230
231            raise ValueError('Invalid endpoint address ' + hex(endpoint_address))
232
233    @synchronized
234    def get_active_configuration(self, device):
235        if self._active_cfg_index is None:
236            self.managed_open()
237            cfg = util.find_descriptor(
238                    device,
239                    bConfigurationValue=self.backend.get_configuration(self.handle)
240                )
241            if cfg is None:
242                raise USBError('Configuration not set')
243            self._active_cfg_index = cfg.index
244            return cfg
245        return device[self._active_cfg_index]
246
247    @synchronized
248    def release_all_interfaces(self, device):
249        claimed = copy.copy(self._claimed_intf)
250        for i in claimed:
251            try:
252                self.managed_release_interface(device, i)
253            except USBError:
254                # Ignore errors when releasing the interfaces
255                # When the device is disconnected, the call may fail
256                pass
257
258    @synchronized
259    def dispose(self, device, close_handle = True):
260        self.release_all_interfaces(device)
261        if close_handle:
262            self.managed_close()
263        self._ep_info.clear()
264        self._active_cfg_index = None
265
266
267class USBError(IOError):
268    r"""Exception class for USB errors.
269
270    Backends must raise this exception when USB related errors occur.  The
271    backend specific error code is available through the 'backend_error_code'
272    member variable.
273    """
274
275    def __init__(self, strerror, error_code = None, errno = None):
276        r"""Initialize the object.
277
278        This initializes the USBError object. The strerror and errno are passed
279        to the parent object. The error_code parameter is attributed to the
280        backend_error_code member variable.
281        """
282
283        IOError.__init__(self, errno, strerror)
284        self.backend_error_code = error_code
285
286class NoBackendError(ValueError):
287    r"Exception class when a valid backend is not found."
288    pass
289
290class Endpoint(object):
291    r"""Represent an endpoint object.
292
293    This class contains all fields of the Endpoint Descriptor according to the
294    USB Specification. You can access them as class properties. For example, to
295    access the field bEndpointAddress of the endpoint descriptor, you can do so:
296
297    >>> import usb.core
298    >>> dev = usb.core.find()
299    >>> for cfg in dev:
300    >>>     for i in cfg:
301    >>>         for e in i:
302    >>>             print e.bEndpointAddress
303    """
304
305    def __init__(self, device, endpoint, interface = 0,
306                    alternate_setting = 0, configuration = 0):
307        r"""Initialize the Endpoint object.
308
309        The device parameter is the device object returned by the find()
310        function. endpoint is the endpoint logical index (not the endpoint
311        address). The configuration parameter is the logical index of the
312        configuration (not the bConfigurationValue field). The interface
313        parameter is the interface logical index (not the bInterfaceNumber
314        field) and alternate_setting is the alternate setting logical index
315        (not the bAlternateSetting value). An interface may have only one
316        alternate setting. In this case, the alternate_setting parameter
317        should be zero. By "logical index" we mean the relative order of the
318        configurations returned by the peripheral as a result of GET_DESCRIPTOR
319        request.
320        """
321        self.device = device
322        self.index = endpoint
323
324        backend = device._ctx.backend
325
326        desc = backend.get_endpoint_descriptor(
327                    device._ctx.dev,
328                    endpoint,
329                    interface,
330                    alternate_setting,
331                    configuration
332                )
333
334        _set_attr(
335                desc,
336                self,
337                (
338                    'bLength',
339                    'bDescriptorType',
340                    'bEndpointAddress',
341                    'bmAttributes',
342                    'wMaxPacketSize',
343                    'bInterval',
344                    'bRefresh',
345                    'bSynchAddress',
346                    'extra_descriptors'
347                )
348            )
349
350    def __repr__(self):
351        return "<" + self._str() + ">"
352
353    def __str__(self):
354        headstr = "      " + self._str() + " "
355
356        if util.endpoint_direction(self.bEndpointAddress) == util.ENDPOINT_IN:
357            direction = "IN"
358        else:
359            direction = "OUT"
360
361        return "%s%s\n" % (headstr, "=" * (60 - len(headstr))) + \
362        "       %-17s:%#7x (7 bytes)\n" % (
363                "bLength", self.bLength) + \
364        "       %-17s:%#7x %s\n" % (
365                "bDescriptorType", self.bDescriptorType,
366                _try_lookup(_lu.descriptors, self.bDescriptorType)) + \
367        "       %-17s:%#7x %s\n" % (
368                "bEndpointAddress", self.bEndpointAddress, direction) + \
369        "       %-17s:%#7x %s\n" % (
370                "bmAttributes", self.bmAttributes,
371                _lu.ep_attributes[(self.bmAttributes & 0x3)]) + \
372        "       %-17s:%#7x (%d bytes)\n" % (
373                "wMaxPacketSize", self.wMaxPacketSize, self.wMaxPacketSize) + \
374        "       %-17s:%#7x" % ("bInterval", self.bInterval)
375
376    def write(self, data, timeout = None):
377        r"""Write data to the endpoint.
378
379        The parameter data contains the data to be sent to the endpoint and
380        timeout is the time limit of the operation. The transfer type and
381        endpoint address are automatically inferred.
382
383        The method returns the number of bytes written.
384
385        For details, see the Device.write() method.
386        """
387        return self.device.write(self, data, timeout)
388
389    def read(self, size_or_buffer, timeout = None):
390        r"""Read data from the endpoint.
391
392        The parameter size_or_buffer is either the number of bytes to
393        read or an array object where the data will be put in and timeout is the
394        time limit of the operation. The transfer type and endpoint address
395        are automatically inferred.
396
397        The method returns either an array object or the number of bytes
398        actually read.
399
400        For details, see the Device.read() method.
401        """
402        return self.device.read(self, size_or_buffer, timeout)
403
404    def clear_halt(self):
405        r"""Clear the halt/status condition of the endpoint."""
406        self.device.clear_halt(self.bEndpointAddress)
407
408    def _str(self):
409        if util.endpoint_direction(self.bEndpointAddress) == util.ENDPOINT_IN:
410            direction = "IN"
411        else:
412            direction = "OUT"
413
414        return (
415            "ENDPOINT 0x%X: %s %s" % (self.bEndpointAddress,
416            _lu.ep_attributes[(self.bmAttributes & 0x3)],
417            direction))
418
419class Interface(object):
420    r"""Represent an interface object.
421
422    This class contains all fields of the Interface Descriptor
423    according to the USB Specification. You may access them as class
424    properties. For example, to access the field bInterfaceNumber
425    of the interface descriptor, you can do so:
426
427    >>> import usb.core
428    >>> dev = usb.core.find()
429    >>> for cfg in dev:
430    >>>     for i in cfg:
431    >>>         print i.bInterfaceNumber
432    """
433
434    def __init__(self, device, interface = 0,
435            alternate_setting = 0, configuration = 0):
436        r"""Initialize the interface object.
437
438        The device parameter is the device object returned by the find()
439        function. The configuration parameter is the logical index of the
440        configuration (not the bConfigurationValue field). The interface
441        parameter is the interface logical index (not the bInterfaceNumber
442        field) and alternate_setting is the alternate setting logical index
443        (not the bAlternateSetting value). An interface may have only one
444        alternate setting. In this case, the alternate_setting parameter
445        should be zero.  By "logical index" we mean the relative order of
446        the configurations returned by the peripheral as a result of
447        GET_DESCRIPTOR request.
448        """
449        self.device = device
450        self.alternate_index = alternate_setting
451        self.index = interface
452        self.configuration = configuration
453
454        backend = device._ctx.backend
455
456        desc = backend.get_interface_descriptor(
457                    self.device._ctx.dev,
458                    interface,
459                    alternate_setting,
460                    configuration
461                )
462
463        _set_attr(
464                desc,
465                self,
466                (
467                    'bLength',
468                    'bDescriptorType',
469                    'bInterfaceNumber',
470                    'bAlternateSetting',
471                    'bNumEndpoints',
472                    'bInterfaceClass',
473                    'bInterfaceSubClass',
474                    'bInterfaceProtocol',
475                    'iInterface',
476                    'extra_descriptors'
477                )
478            )
479
480    def __repr__(self):
481        return "<" + self._str() + ">"
482
483    def __str__(self):
484        """Show all information for the interface."""
485
486        string = self._get_full_descriptor_str()
487        for endpoint in self:
488            string += "\n" + str(endpoint)
489        return string
490
491    def endpoints(self):
492        r"""Return a tuple of the interface endpoints."""
493        return tuple(self)
494
495    def set_altsetting(self):
496        r"""Set the interface alternate setting."""
497        self.device.set_interface_altsetting(
498            self.bInterfaceNumber,
499            self.bAlternateSetting)
500
501    def __iter__(self):
502        r"""Iterate over all endpoints of the interface."""
503        for i in range(self.bNumEndpoints):
504            yield Endpoint(
505                    self.device,
506                    i,
507                    self.index,
508                    self.alternate_index,
509                    self.configuration)
510
511    def __getitem__(self, index):
512        r"""Return the Endpoint object in the given position."""
513        return Endpoint(
514                self.device,
515                index,
516                self.index,
517                self.alternate_index,
518                self.configuration)
519
520    def _str(self):
521        if self.bAlternateSetting:
522            alt_setting = ", %d" % self.bAlternateSetting
523        else:
524            alt_setting = ""
525
526        return "INTERFACE %d%s: %s" % (self.bInterfaceNumber, alt_setting,
527            _try_lookup(_lu.interface_classes, self.bInterfaceClass,
528                default = "Unknown Class"))
529
530    def _get_full_descriptor_str(self):
531        headstr = "    " + self._str() + " "
532        return "%s%s\n" % (headstr, "=" * (60 - len(headstr))) + \
533        "     %-19s:%#7x (9 bytes)\n" % (
534            "bLength", self.bLength) + \
535        "     %-19s:%#7x %s\n" % (
536            "bDescriptorType", self.bDescriptorType,
537            _try_lookup(_lu.descriptors, self.bDescriptorType)) + \
538        "     %-19s:%#7x\n" % (
539            "bInterfaceNumber", self.bInterfaceNumber) + \
540        "     %-19s:%#7x\n" % (
541            "bAlternateSetting", self.bAlternateSetting) + \
542        "     %-19s:%#7x\n" % (
543            "bNumEndpoints", self.bNumEndpoints) + \
544        "     %-19s:%#7x %s\n" % (
545            "bInterfaceClass", self.bInterfaceClass,
546            _try_lookup(_lu.interface_classes, self.bInterfaceClass)) + \
547        "     %-19s:%#7x\n" % (
548            "bInterfaceSubClass", self.bInterfaceSubClass) + \
549        "     %-19s:%#7x\n" % (
550            "bInterfaceProtocol", self.bInterfaceProtocol) + \
551        "     %-19s:%#7x %s" % (
552            "iInterface", self.iInterface,
553            _try_get_string(self.device, self.iInterface))
554
555
556class Configuration(object):
557    r"""Represent a configuration object.
558
559    This class contains all fields of the Configuration Descriptor according to
560    the USB Specification. You may access them as class properties.  For
561    example, to access the field bConfigurationValue of the configuration
562    descriptor, you can do so:
563
564    >>> import usb.core
565    >>> dev = usb.core.find()
566    >>> for cfg in dev:
567    >>>     print cfg.bConfigurationValue
568    """
569
570    def __init__(self, device, configuration = 0):
571        r"""Initialize the configuration object.
572
573        The device parameter is the device object returned by the find()
574        function. The configuration parameter is the logical index of the
575        configuration (not the bConfigurationValue field). By "logical index"
576        we mean the relative order of the configurations returned by the
577        peripheral as a result of GET_DESCRIPTOR request.
578        """
579        self.device = device
580        self.index = configuration
581
582        backend = device._ctx.backend
583
584        desc = backend.get_configuration_descriptor(
585                self.device._ctx.dev,
586                configuration
587            )
588
589        _set_attr(
590                desc,
591                self,
592                (
593                    'bLength',
594                    'bDescriptorType',
595                    'wTotalLength',
596                    'bNumInterfaces',
597                    'bConfigurationValue',
598                    'iConfiguration',
599                    'bmAttributes',
600                    'bMaxPower',
601                    'extra_descriptors'
602                )
603            )
604
605    def __repr__(self):
606        return "<" + self._str() + ">"
607
608    def __str__(self):
609        string = self._get_full_descriptor_str()
610        for interface in self:
611            string += "\n%s" % str(interface)
612        return string
613
614    def interfaces(self):
615        r"""Return a tuple of the configuration interfaces."""
616        return tuple(self)
617
618    def set(self):
619        r"""Set this configuration as the active one."""
620        self.device.set_configuration(self.bConfigurationValue)
621
622    def __iter__(self):
623        r"""Iterate over all interfaces of the configuration."""
624        for i in range(self.bNumInterfaces):
625            alt = 0
626            try:
627                while True:
628                    yield Interface(self.device, i, alt, self.index)
629                    alt += 1
630            except (USBError, IndexError):
631                pass
632
633    def __getitem__(self, index):
634        r"""Return the Interface object in the given position.
635
636        index is a tuple of two values with interface index and
637        alternate setting index, respectivally. Example:
638
639        >>> interface = config[(0, 0)]
640        """
641        return Interface(self.device, index[0], index[1], self.index)
642
643
644    def _str(self):
645        return "CONFIGURATION %d: %d mA" % (
646            self.bConfigurationValue,
647            _lu.MAX_POWER_UNITS_USB2p0 * self.bMaxPower)
648
649    def _get_full_descriptor_str(self):
650        headstr = "  " + self._str() + " "
651        if self.bmAttributes & (1<<6):
652            powered = "Self"
653        else:
654            powered = "Bus"
655
656        if self.bmAttributes & (1<<5):
657            remote_wakeup = ", Remote Wakeup"
658        else:
659            remote_wakeup = ""
660
661        return "%s%s\n" % (headstr, "=" * (60 - len(headstr))) + \
662        "   %-21s:%#7x (9 bytes)\n" % (
663            "bLength", self.bLength) + \
664        "   %-21s:%#7x %s\n" % (
665            "bDescriptorType", self.bDescriptorType,
666            _try_lookup(_lu.descriptors, self.bDescriptorType)) + \
667        "   %-21s:%#7x (%d bytes)\n" % (
668            "wTotalLength", self.wTotalLength, self.wTotalLength) + \
669        "   %-21s:%#7x\n" % (
670            "bNumInterfaces", self.bNumInterfaces) + \
671        "   %-21s:%#7x\n" % (
672            "bConfigurationValue", self.bConfigurationValue) + \
673        "   %-21s:%#7x %s\n" % (
674            "iConfiguration", self.iConfiguration,
675            _try_get_string(self.device, self.iConfiguration)) + \
676        "   %-21s:%#7x %s Powered%s\n" % (
677            "bmAttributes", self.bmAttributes, powered, remote_wakeup
678            # bit 7 is high, bit 4..0 are 0
679            ) + \
680        "   %-21s:%#7x (%d mA)" % (
681            "bMaxPower", self.bMaxPower,
682            _lu.MAX_POWER_UNITS_USB2p0 * self.bMaxPower)
683            # FIXME : add a check for superspeed vs usb 2.0
684
685class Device(_objfinalizer.AutoFinalizedObject):
686    r"""Device object.
687
688    This class contains all fields of the Device Descriptor according to the
689    USB Specification. You may access them as class properties.  For example,
690    to access the field bDescriptorType of the device descriptor, you can
691    do so:
692
693    >>> import usb.core
694    >>> dev = usb.core.find()
695    >>> dev.bDescriptorType
696
697    Additionally, the class provides methods to communicate with the hardware.
698    Typically, an application will first call the set_configuration() method to
699    put the device in a known configured state, optionally call the
700    set_interface_altsetting() to select the alternate setting (if there is
701    more than one) of the interface used, and call the write() and read()
702    methods to send and receive data, respectively.
703
704    When working in a new hardware, the first try could be like this:
705
706    >>> import usb.core
707    >>> dev = usb.core.find(idVendor=myVendorId, idProduct=myProductId)
708    >>> dev.set_configuration()
709    >>> dev.write(1, 'test')
710
711    This sample finds the device of interest (myVendorId and myProductId should
712    be replaced by the corresponding values of your device), then configures
713    the device (by default, the configuration value is 1, which is a typical
714    value for most devices) and then writes some data to the endpoint 0x01.
715
716    Timeout values for the write, read and ctrl_transfer methods are specified
717    in miliseconds. If the parameter is omitted, Device.default_timeout value
718    will be used instead. This property can be set by the user at anytime.
719    """
720
721    def __repr__(self):
722        return "<" + self._str() + ">"
723
724    def __str__(self):
725        string = self._get_full_descriptor_str()
726        try:
727            for configuration in self:
728                string += "\n%s" % str(configuration)
729        except USBError:
730            try:
731                configuration = self.get_active_configuration()
732                string += "\n%s" % (configuration.info)
733            except USBError:
734                string += " USBError Accessing Configurations"
735        return string
736
737    def configurations(self):
738        r"""Return a tuple of the device configurations."""
739        return tuple(self)
740
741    def __init__(self, dev, backend):
742        r"""Initialize the Device object.
743
744        Library users should normally get a Device instance through
745        the find function. The dev parameter is the identification
746        of a device to the backend and its meaning is opaque outside
747        of it. The backend parameter is a instance of a backend
748        object.
749        """
750        self._ctx = _ResourceManager(dev, backend)
751        self.__default_timeout = _DEFAULT_TIMEOUT
752        self._serial_number, self._product, self._manufacturer = None, None, None
753        self._langids = None
754
755        desc = backend.get_device_descriptor(dev)
756
757        _set_attr(
758                desc,
759                self,
760                (
761                    'bLength',
762                    'bDescriptorType',
763                    'bcdUSB',
764                    'bDeviceClass',
765                    'bDeviceSubClass',
766                    'bDeviceProtocol',
767                    'bMaxPacketSize0',
768                    'idVendor',
769                    'idProduct',
770                    'bcdDevice',
771                    'iManufacturer',
772                    'iProduct',
773                    'iSerialNumber',
774                    'bNumConfigurations',
775                    'address',
776                    'bus',
777                    'port_number',
778                    'port_numbers',
779                    'speed',
780                )
781            )
782
783        if desc.bus is not None:
784            self.bus = int(desc.bus)
785        else:
786            self.bus = None
787
788        if desc.address is not None:
789            self.address = int(desc.address)
790        else:
791            self.address = None
792
793        if desc.port_number is not None:
794            self.port_number = int(desc.port_number)
795        else:
796            self.port_number = None
797
798        if desc.speed is not None:
799            self.speed = int(desc.speed)
800        else:
801            self.speed = None
802
803    @property
804    def langids(self):
805        """ Return the USB device's supported language ID codes.
806
807        These are 16-bit codes familiar to Windows developers, where for
808        example instead of en-US you say 0x0409. USB_LANGIDS.pdf on the usb.org
809        developer site for more info. String requests using a LANGID not
810        in this array should not be sent to the device.
811
812        This property will cause some USB traffic the first time it is accessed
813        and cache the resulting value for future use.
814        """
815        if self._langids is None:
816            try:
817                self._langids = util.get_langids(self)
818            except USBError:
819                self._langids = ()
820        return self._langids
821
822    @property
823    def serial_number(self):
824        """ Return the USB device's serial number string descriptor.
825
826        This property will cause some USB traffic the first time it is accessed
827        and cache the resulting value for future use.
828        """
829        if self._serial_number is None:
830            self._serial_number = util.get_string(self, self.iSerialNumber)
831        return self._serial_number
832
833    @property
834    def product(self):
835        """ Return the USB device's product string descriptor.
836
837        This property will cause some USB traffic the first time it is accessed
838        and cache the resulting value for future use.
839        """
840        if self._product is None:
841            self._product = util.get_string(self, self.iProduct)
842        return self._product
843
844    @property
845    def manufacturer(self):
846        """ Return the USB device's manufacturer string descriptor.
847
848        This property will cause some USB traffic the first time it is accessed
849        and cache the resulting value for future use.
850        """
851        if self._manufacturer is None:
852            self._manufacturer = util.get_string(self, self.iManufacturer)
853        return self._manufacturer
854
855    @property
856    def backend(self):
857        """Return the backend being used by the device."""
858        return self._ctx.backend
859
860    def set_configuration(self, configuration = None):
861        r"""Set the active configuration.
862
863        The configuration parameter is the bConfigurationValue field of the
864        configuration you want to set as active. If you call this method
865        without parameter, it will use the first configuration found.  As a
866        device hardly ever has more than one configuration, calling the method
867        without arguments is enough to get the device ready.
868        """
869        self._ctx.managed_set_configuration(self, configuration)
870
871    def get_active_configuration(self):
872        r"""Return a Configuration object representing the current
873        configuration set.
874        """
875        return self._ctx.get_active_configuration(self)
876
877    def set_interface_altsetting(self, interface = None, alternate_setting = None):
878        r"""Set the alternate setting for an interface.
879
880        When you want to use an interface and it has more than one alternate
881        setting, you should call this method to select the appropriate
882        alternate setting. If you call the method without one or the two
883        parameters, it will be selected the first one found in the Device in
884        the same way of the set_configuration method.
885
886        Commonly, an interface has only one alternate setting and this call is
887        not necessary. For most devices, either it has more than one
888        alternate setting or not, it is not harmful to make a call to this
889        method with no arguments, as devices will silently ignore the request
890        when there is only one alternate setting, though the USB Spec allows
891        devices with no additional alternate setting return an error to the
892        Host in response to a SET_INTERFACE request.
893
894        If you are in doubt, you may want to call it with no arguments wrapped
895        by a try/except clause:
896
897        >>> try:
898        >>>     dev.set_interface_altsetting()
899        >>> except usb.core.USBError:
900        >>>     pass
901        """
902        self._ctx.managed_set_interface(self, interface, alternate_setting)
903
904    def clear_halt(self, ep):
905        r""" Clear the halt/stall condition for the endpoint ep."""
906        if isinstance(ep, Endpoint):
907            ep = ep.bEndpointAddress
908        self._ctx.managed_open()
909        self._ctx.backend.clear_halt(self._ctx.handle, ep)
910
911    def reset(self):
912        r"""Reset the device."""
913        self._ctx.managed_open()
914        self._ctx.dispose(self, False)
915        self._ctx.backend.reset_device(self._ctx.handle)
916        self._ctx.dispose(self, True)
917
918    def write(self, endpoint, data, timeout = None):
919        r"""Write data to the endpoint.
920
921        This method is used to send data to the device. The endpoint parameter
922        corresponds to the bEndpointAddress member whose endpoint you want to
923        communicate with.
924
925        The data parameter should be a sequence like type convertible to
926        the array type (see array module).
927
928        The timeout is specified in miliseconds.
929
930        The method returns the number of bytes written.
931        """
932        backend = self._ctx.backend
933
934        fn_map = {
935                    util.ENDPOINT_TYPE_BULK:backend.bulk_write,
936                    util.ENDPOINT_TYPE_INTR:backend.intr_write,
937                    util.ENDPOINT_TYPE_ISO:backend.iso_write
938                }
939
940        intf, ep = self._ctx.setup_request(self, endpoint)
941        fn = fn_map[util.endpoint_type(ep.bmAttributes)]
942
943        return fn(
944                self._ctx.handle,
945                ep.bEndpointAddress,
946                intf.bInterfaceNumber,
947                _interop.as_array(data),
948                self.__get_timeout(timeout)
949            )
950
951    def read(self, endpoint, size_or_buffer, timeout = None):
952        r"""Read data from the endpoint.
953
954        This method is used to receive data from the device. The endpoint
955        parameter corresponds to the bEndpointAddress member whose endpoint
956        you want to communicate with. The size_or_buffer parameter either
957        tells how many bytes you want to read or supplies the buffer to
958        receive the data (it *must* be an object of the type array).
959
960        The timeout is specified in miliseconds.
961
962        If the size_or_buffer parameter is the number of bytes to read, the
963        method returns an array object with the data read. If the
964        size_or_buffer parameter is an array object, it returns the number
965        of bytes actually read.
966        """
967        backend = self._ctx.backend
968
969        fn_map = {
970                    util.ENDPOINT_TYPE_BULK:backend.bulk_read,
971                    util.ENDPOINT_TYPE_INTR:backend.intr_read,
972                    util.ENDPOINT_TYPE_ISO:backend.iso_read
973                }
974
975        intf, ep = self._ctx.setup_request(self, endpoint)
976        fn = fn_map[util.endpoint_type(ep.bmAttributes)]
977
978        if isinstance(size_or_buffer, array.array):
979            buff = size_or_buffer
980        else: # here we consider it is a integer
981            buff = util.create_buffer(size_or_buffer)
982
983        ret = fn(
984                self._ctx.handle,
985                ep.bEndpointAddress,
986                intf.bInterfaceNumber,
987                buff,
988                self.__get_timeout(timeout))
989
990        if isinstance(size_or_buffer, array.array):
991            return ret
992        elif ret != len(buff) * buff.itemsize:
993            return buff[:ret]
994        else:
995            return buff
996
997    def ctrl_transfer(self, bmRequestType, bRequest, wValue=0, wIndex=0,
998            data_or_wLength = None, timeout = None):
999        r"""Do a control transfer on the endpoint 0.
1000
1001        This method is used to issue a control transfer over the endpoint 0
1002        (endpoint 0 is required to always be a control endpoint).
1003
1004        The parameters bmRequestType, bRequest, wValue and wIndex are the same
1005        of the USB Standard Control Request format.
1006
1007        Control requests may or may not have a data payload to write/read.
1008        In cases which it has, the direction bit of the bmRequestType
1009        field is used to infer the desired request direction. For
1010        host to device requests (OUT), data_or_wLength parameter is
1011        the data payload to send, and it must be a sequence type convertible
1012        to an array object. In this case, the return value is the number
1013        of bytes written in the data payload. For device to host requests
1014        (IN), data_or_wLength is either the wLength parameter of the control
1015        request specifying the number of bytes to read in data payload, and
1016        the return value is an array object with data read, or an array
1017        object which the data will be read to, and the return value is the
1018        number of bytes read.
1019        """
1020        try:
1021            buff = util.create_buffer(data_or_wLength)
1022        except TypeError:
1023            buff = _interop.as_array(data_or_wLength)
1024
1025        self._ctx.managed_open()
1026
1027        # Thanks to Johannes Stezenbach to point me out that we need to
1028        # claim the recipient interface
1029        recipient = bmRequestType & 3
1030        rqtype = bmRequestType & (3 << 5)
1031        if recipient == util.CTRL_RECIPIENT_INTERFACE \
1032                and rqtype != util.CTRL_TYPE_VENDOR:
1033            interface_number = wIndex & 0xff
1034            self._ctx.managed_claim_interface(self, interface_number)
1035
1036        ret = self._ctx.backend.ctrl_transfer(
1037                                    self._ctx.handle,
1038                                    bmRequestType,
1039                                    bRequest,
1040                                    wValue,
1041                                    wIndex,
1042                                    buff,
1043                                    self.__get_timeout(timeout))
1044
1045        if isinstance(data_or_wLength, array.array) \
1046                or util.ctrl_direction(bmRequestType) == util.CTRL_OUT:
1047            return ret
1048        elif ret != len(buff) * buff.itemsize:
1049            return buff[:ret]
1050        else:
1051            return buff
1052
1053    def is_kernel_driver_active(self, interface):
1054        r"""Determine if there is kernel driver associated with the interface.
1055
1056        If a kernel driver is active, the object will be unable to perform
1057        I/O.
1058
1059        The interface parameter is the device interface number to check.
1060        """
1061        self._ctx.managed_open()
1062        return self._ctx.backend.is_kernel_driver_active(
1063                self._ctx.handle,
1064                interface)
1065
1066    def detach_kernel_driver(self, interface):
1067        r"""Detach a kernel driver.
1068
1069        If successful, you will then be able to perform I/O.
1070
1071        The interface parameter is the device interface number to detach the
1072        driver from.
1073        """
1074        self._ctx.managed_open()
1075        self._ctx.backend.detach_kernel_driver(
1076            self._ctx.handle,
1077            interface)
1078
1079    def attach_kernel_driver(self, interface):
1080        r"""Re-attach an interface's kernel driver, which was previously
1081        detached using detach_kernel_driver().
1082
1083        The interface parameter is the device interface number to attach the
1084        driver to.
1085        """
1086        self._ctx.managed_open()
1087        self._ctx.backend.attach_kernel_driver(
1088            self._ctx.handle,
1089            interface)
1090
1091    def __iter__(self):
1092        r"""Iterate over all configurations of the device."""
1093        for i in range(self.bNumConfigurations):
1094            yield Configuration(self, i)
1095
1096    def __getitem__(self, index):
1097        r"""Return the Configuration object in the given position."""
1098        return Configuration(self, index)
1099
1100    def _finalize_object(self):
1101        self._ctx.dispose(self)
1102
1103    def __get_timeout(self, timeout):
1104        if timeout is not None:
1105            return timeout
1106        return self.__default_timeout
1107
1108    def __set_def_tmo(self, tmo):
1109        if tmo < 0:
1110            raise ValueError('Timeout cannot be a negative value')
1111        self.__default_timeout = tmo
1112
1113    def __get_def_tmo(self):
1114        return self.__default_timeout
1115
1116    def _str(self):
1117        return "DEVICE ID %04x:%04x on Bus %03d Address %03d" % (
1118            self.idVendor, self.idProduct, self.bus, self.address)
1119
1120    def _get_full_descriptor_str(self):
1121        headstr = self._str() + " "
1122
1123        if self.bcdUSB & 0xf:
1124            low_bcd_usb = str(self.bcdUSB & 0xf)
1125        else:
1126            low_bcd_usb = ""
1127
1128        if self.bcdDevice & 0xf:
1129            low_bcd_device = str(self.bcdDevice & 0xf)
1130        else:
1131            low_bcd_device = ""
1132
1133        return "%s%s\n" %  (headstr, "=" * (60 - len(headstr))) + \
1134        " %-23s:%#7x (18 bytes)\n" % (
1135            "bLength", self.bLength) + \
1136        " %-23s:%#7x %s\n" % (
1137            "bDescriptorType", self.bDescriptorType,
1138            _try_lookup(_lu.descriptors, self.bDescriptorType)) + \
1139        " %-23s:%#7x USB %d.%d%s\n" % (
1140            "bcdUSB", self.bcdUSB, (self.bcdUSB & 0xff00)>>8,
1141            (self.bcdUSB & 0xf0) >> 4, low_bcd_usb) + \
1142        " %-23s:%#7x %s\n" % (
1143            "bDeviceClass", self.bDeviceClass,
1144            _try_lookup(_lu.device_classes, self.bDeviceClass)) + \
1145        " %-23s:%#7x\n" % (
1146            "bDeviceSubClass", self.bDeviceSubClass) + \
1147        " %-23s:%#7x\n" % (
1148            "bDeviceProtocol", self.bDeviceProtocol) + \
1149        " %-23s:%#7x (%d bytes)\n" % (
1150            "bMaxPacketSize0", self.bMaxPacketSize0, self.bMaxPacketSize0) + \
1151        " %-23s: %#06x\n" % (
1152            "idVendor", self.idVendor) + \
1153        " %-23s: %#06x\n" % (
1154            "idProduct", self.idProduct) + \
1155        " %-23s:%#7x Device %d.%d%s\n" % (
1156            "bcdDevice", self.bcdDevice, (self.bcdDevice & 0xff00)>>8,
1157            (self.bcdDevice & 0xf0) >> 4, low_bcd_device) + \
1158        " %-23s:%#7x %s\n" % (
1159            "iManufacturer", self.iManufacturer,
1160            _try_get_string(self, self.iManufacturer)) + \
1161        " %-23s:%#7x %s\n" % (
1162            "iProduct", self.iProduct,
1163            _try_get_string(self, self.iProduct)) + \
1164        " %-23s:%#7x %s\n" % (
1165            "iSerialNumber", self.iSerialNumber,
1166            _try_get_string(self, self.iSerialNumber)) + \
1167        " %-23s:%#7x" % (
1168            "bNumConfigurations", self.bNumConfigurations)
1169
1170    default_timeout = property(
1171                        __get_def_tmo,
1172                        __set_def_tmo,
1173                        doc = 'Default timeout for transfer I/O functions'
1174                    )
1175
1176
1177def find(find_all=False, backend = None, custom_match = None, **args):
1178    r"""Find an USB device and return it.
1179
1180    find() is the function used to discover USB devices.  You can pass as
1181    arguments any combination of the USB Device Descriptor fields to match a
1182    device. For example:
1183
1184    find(idVendor=0x3f4, idProduct=0x2009)
1185
1186    will return the Device object for the device with idVendor field equals
1187    to 0x3f4 and idProduct equals to 0x2009.
1188
1189    If there is more than one device which matchs the criteria, the first one
1190    found will be returned. If a matching device cannot be found the function
1191    returns None. If you want to get all devices, you can set the parameter
1192    find_all to True, then find will return an iterator with all matched devices.
1193    If no matching device is found, it will return an empty iterator. Example:
1194
1195    for printer in find(find_all=True, bDeviceClass=7):
1196        print (printer)
1197
1198    This call will get all the USB printers connected to the system.  (actually
1199    may be not, because some devices put their class information in the
1200    Interface Descriptor).
1201
1202    You can also use a customized match criteria:
1203
1204    dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
1205
1206    A more accurate printer finder using a customized match would be like
1207    so:
1208
1209    def is_printer(dev):
1210        import usb.util
1211        if dev.bDeviceClass == 7:
1212            return True
1213        for cfg in dev:
1214            if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
1215                return True
1216
1217    for printer in find(find_all=True, custom_match = is_printer):
1218        print (printer)
1219
1220    Now even if the device class code is in the interface descriptor the
1221    printer will be found.
1222
1223    You can combine a customized match with device descriptor fields. In this
1224    case, the fields must match and the custom_match must return True. In the
1225    our previous example, if we would like to get all printers belonging to the
1226    manufacturer 0x3f4, the code would be like so:
1227
1228    printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer))
1229
1230    If you want to use find as a 'list all devices' function, just call
1231    it with find_all = True:
1232
1233    devices = list(find(find_all=True))
1234
1235    Finally, you can pass a custom backend to the find function:
1236
1237    find(backend = MyBackend())
1238
1239    PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.  If you
1240    do not supply a backend explicitly, find() function will select one of the
1241    predefineds backends according to system availability.
1242
1243    Backends are explained in the usb.backend module.
1244    """
1245    def device_iter(**kwargs):
1246        for dev in backend.enumerate_devices():
1247            d = Device(dev, backend)
1248            tests = (val == getattr(d, key) for key, val in kwargs.items())
1249            if _interop._all(tests) and (custom_match is None or custom_match(d)):
1250                yield d
1251
1252    if backend is None:
1253        import usb.backend.libusb1 as libusb1
1254        import usb.backend.libusb0 as libusb0
1255        import usb.backend.openusb as openusb
1256
1257        for m in (libusb1, openusb, libusb0):
1258            backend = m.get_backend()
1259            if backend is not None:
1260                _logger.info('find(): using backend "%s"', m.__name__)
1261                break
1262        else:
1263            raise NoBackendError('No backend available')
1264
1265    if find_all:
1266        return device_iter(**args)
1267    else:
1268        try:
1269            return _interop._next(device_iter(**args))
1270        except StopIteration:
1271            return None
1272
1273def show_devices(verbose=False, **kwargs):
1274    """Show information about connected devices.
1275
1276    The verbose flag sets to verbose or not.
1277    **kwargs are passed directly to the find() function.
1278    """
1279    kwargs["find_all"] = True
1280    devices = find(**kwargs)
1281    strings = ""
1282    for device in devices:
1283        if not verbose:
1284            strings +=  "%s, %s\n" % (device._str(), _try_lookup(
1285                _lu.device_classes, device.bDeviceClass))
1286        else:
1287            strings += "%s\n\n" % str(device)
1288
1289    return _DescriptorInfo(strings)
1290