lib/hidapi/engine.rb
def get_device_by_path(path, options = {})

      # Our linux setup routine creates convenient /dev/hidapi/* links.
      # If the user wants to open one of those, we can simple parse the link to generate
      # the path that the library expects.
      if File.exist?(path)

        hidapi_regex = /^\/dev\/hidapi\//
        usb_bus_regex = /^\/dev\/bus\/usb\/(?<BUS>\d+)\/(?<ADDR>\d+)$/

        if hidapi_regex.match(path)
          path = File.expand_path(File.readlink(path), File.dirname(path))
        elsif !usb_bus_regex.match(path)
          raise HIDAPI::DevicePathInvalid, 'Cannot open file paths other than /dev/hidapi/XXX or /dev/bus/usb/XXX/XXX paths.'
        end

        # path should now be in the form /dev/bus/usb/AAA/BBB
        match = usb_bus_regex.match(path)

        raise HIDAPI::DevicePathInvalid, "Link target does not appear valid (#{path})." unless match

        interface = (options.delete(:interface) || 0).to_s(16)

        path = HIDAPI::Device.validate_path("#{match['BUS']}:#{match['ADDR']}:#{interface}")
      end

      valid_path = HIDAPI::Device.validate_path(path)
      raise HIDAPI::DevicePathInvalid, "Path should be in BUS:ADDRESS:INTERFACE format with each value being in hexadecimal (ie - 0001:01A:00), not #{path}." unless valid_path
      path = valid_path

      klass = (options || {}).delete(:as) || 'HIDAPI::Device'
      klass = Object.const_get(klass) unless klass == :no_mapping

      enumerate(as: :no_mapping).each do |usb_dev|
        usb_dev.settings.each do |intf_desc|
          if intf_desc.bInterfaceClass == HID_CLASS
            dev_path = HIDAPI::Device.make_path(usb_dev, intf_desc.bInterfaceNumber)
            if dev_path == path
              if klass != :no_mapping
                return klass.new(usb_dev, intf_desc.bInterfaceNumber)
              else
                return usb_dev
              end
            end
          end
        end
      end
    end
def get_device_by_path(path, options = {})

      # Our linux setup routine creates convenient /dev/hidapi/* links.
      # If the user wants to open one of those, we can simple parse the link to generate
      # the path that the library expects.
      if File.exist?(path)

        hidapi_regex = /^\/dev\/hidapi\//
        usb_bus_regex = /^\/dev\/bus\/usb\/(?<BUS>\d+)\/(?<ADDR>\d+)$/

        if hidapi_regex.match(path)
          path = File.expand_path(File.readlink(path), File.dirname(path))
        elsif !usb_bus_regex.match(path)
          raise HIDAPI::DevicePathInvalid, 'Cannot open file paths other than /dev/hidapi/XXX or /dev/bus/usb/XXX/XXX paths.'
        end

        # path should now be in the form /dev/bus/usb/AAA/BBB
        match = usb_bus_regex.match(path)

        raise HIDAPI::DevicePathInvalid, "Link target does not appear valid (#{path})." unless match

        interface = (options.delete(:interface) || 0).to_s(16)

        path = HIDAPI::Device.validate_path("#{match['BUS']}:#{match['ADDR']}:#{interface}")
      end

      valid_path = HIDAPI::Device.validate_path(path)
      raise HIDAPI::DevicePathInvalid, "Path should be in BUS:ADDRESS:INTERFACE format with each value being in hexadecimal (ie - 0001:01A:00), not #{path}." unless valid_path
      path = valid_path

      klass = (options || {}).delete(:as) || 'HIDAPI::Device'
      klass = Object.const_get(klass) unless klass == :no_mapping

      enumerate(as: :no_mapping).each do |usb_dev|
        usb_dev.settings.each do |intf_desc|
          if intf_desc.bInterfaceClass == HID_CLASS
            dev_path = HIDAPI::Device.make_path(usb_dev, intf_desc.bInterfaceNumber)
            if dev_path == path
              if klass != :no_mapping
                return klass.new(usb_dev, intf_desc.bInterfaceNumber)
              else
                return usb_dev
              end
            end
          end
        end
      end
    end
Gets the device with the specified path.