def devices(filter_hash={})
      device_list.select do |dev|
        ( !filter_hash[:bClass] || (dev.bDeviceClass==CLASS_PER_INTERFACE ?
                             dev.settings.map(&:bInterfaceClass).&([filter_hash[:bClass]].flatten).any? :
                             [filter_hash[:bClass]].flatten.include?(dev.bDeviceClass))) &&
        ( !filter_hash[:bSubClass] || (dev.bDeviceClass==CLASS_PER_INTERFACE ?
                             dev.settings.map(&:bInterfaceSubClass).&([filter_hash[:bSubClass]].flatten).any? :
                             [filter_hash[:bSubClass]].flatten.include?(dev.bDeviceSubClass))) &&
        ( !filter_hash[:bProtocol] || (dev.bDeviceClass==CLASS_PER_INTERFACE ?
                             dev.settings.map(&:bInterfaceProtocol).&([filter_hash[:bProtocol]].flatten).any? :
                             [filter_hash[:bProtocol]].flatten.include?(dev.bDeviceProtocol))) &&
        ( !filter_hash[:bMaxPacketSize0] || [filter_hash[:bMaxPacketSize0]].flatten.include?(dev.bMaxPacketSize0) ) &&
        ( !filter_hash[:idVendor] || [filter_hash[:idVendor]].flatten.include?(dev.idVendor) ) &&
        ( !filter_hash[:idProduct] || [filter_hash[:idProduct]].flatten.include?(dev.idProduct) ) &&
        ( !filter_hash[:bcdUSB] || [filter_hash[:bcdUSB]].flatten.include?(dev.bcdUSB) ) &&
        ( !filter_hash[:bcdDevice] || [filter_hash[:bcdDevice]].flatten.include?(dev.bcdDevice) )
      end
    end
def devices(filter_hash={})
      device_list.select do |dev|
        ( !filter_hash[:bClass] || (dev.bDeviceClass==CLASS_PER_INTERFACE ?
                             dev.settings.map(&:bInterfaceClass).&([filter_hash[:bClass]].flatten).any? :
                             [filter_hash[:bClass]].flatten.include?(dev.bDeviceClass))) &&
        ( !filter_hash[:bSubClass] || (dev.bDeviceClass==CLASS_PER_INTERFACE ?
                             dev.settings.map(&:bInterfaceSubClass).&([filter_hash[:bSubClass]].flatten).any? :
                             [filter_hash[:bSubClass]].flatten.include?(dev.bDeviceSubClass))) &&
        ( !filter_hash[:bProtocol] || (dev.bDeviceClass==CLASS_PER_INTERFACE ?
                             dev.settings.map(&:bInterfaceProtocol).&([filter_hash[:bProtocol]].flatten).any? :
                             [filter_hash[:bProtocol]].flatten.include?(dev.bDeviceProtocol))) &&
        ( !filter_hash[:bMaxPacketSize0] || [filter_hash[:bMaxPacketSize0]].flatten.include?(dev.bMaxPacketSize0) ) &&
        ( !filter_hash[:idVendor] || [filter_hash[:idVendor]].flatten.include?(dev.idVendor) ) &&
        ( !filter_hash[:idProduct] || [filter_hash[:idProduct]].flatten.include?(dev.idProduct) ) &&
        ( !filter_hash[:bcdUSB] || [filter_hash[:bcdUSB]].flatten.include?(dev.bcdUSB) ) &&
        ( !filter_hash[:bcdDevice] || [filter_hash[:bcdDevice]].flatten.include?(dev.bcdDevice) )
      end
    end
Obtain a list of devices currently attached to the USB system, optionally matching certain criteria.

 @param [Hash] filter_hash  A number of criteria can be defined in key-value pairs.
   Only devices that equal all given criterions will be returned. If a criterion is
   not specified or its value is +nil+, any device will match that criterion.
   The following criteria can be filtered:
   * <tt>:idVendor</tt>, <tt>:idProduct</tt> (+FixNum+) for matching vendor/product ID,
   * <tt>:bClass</tt>, <tt>:bSubClass</tt>, <tt>:bProtocol</tt> (+FixNum+) for the device type -
     Devices using CLASS_PER_INTERFACE will match, if any of the interfaces match.
   * <tt>:bcdUSB</tt>, <tt>:bcdDevice</tt>, <tt>:bMaxPacketSize0</tt> (+FixNum+) for the
     USB and device release numbers.
   Criteria can also specified as Array of several alternative values.

 @example
   # Return all devices of vendor 0x0ab1 where idProduct is 3 or 4:
   context.device idVendor: 0x0ab1, idProduct: [0x0003, 0x0004]

 @return [Array<LIBUSB::Device>]