From 9698bfece709ae429b17c3da40b91ae906af60cb Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Sat, 28 Mar 2020 23:15:48 +0200 Subject: [PATCH] genesys: Add support for matching devices by bcdDevice --- backend/genesys/genesys.cpp | 15 +++++++---- backend/genesys/low.h | 27 +++++++++++++++++-- backend/genesys/test_settings.cpp | 10 ++++++- backend/genesys/test_settings.h | 2 ++ .../backend/genesys/session_config_test.cpp | 5 +++- 5 files changed, 50 insertions(+), 9 deletions(-) diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index 2fbe96260..ea42f006e 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -4794,12 +4794,12 @@ check_present (SANE_String_Const devname) noexcept } static Genesys_Device* attach_usb_device(const char* devname, - std::uint16_t vendor_id, std::uint16_t product_id) + std::uint16_t vendor_id, std::uint16_t product_id, + std::uint16_t bcd_device) { UsbDeviceEntry* found_usb_dev = nullptr; for (auto& usb_dev : *s_usb_devices) { - if (usb_dev.vendor_id() == vendor_id && - usb_dev.product_id() == product_id) + if (usb_dev.matches(vendor_id, product_id, bcd_device)) { found_usb_dev = &usb_dev; break; @@ -4847,6 +4847,10 @@ static Genesys_Device* attach_device_by_name(SANE_String_Const devname, bool may int vendor, product; usb_dev.get_vendor_product(vendor, product); + + // FIXME: enable when get_bcd_device call can be recorded and replayed + // auto bcd_device = usb_dev.get_bcd_device(); + std::uint16_t bcd_device = 0xffff; usb_dev.close(); /* KV-SS080 is an auxiliary device which requires a master device to be here */ @@ -4861,7 +4865,7 @@ static Genesys_Device* attach_device_by_name(SANE_String_Const devname, bool may } } - Genesys_Device* dev = attach_usb_device(devname, vendor, product); + Genesys_Device* dev = attach_usb_device(devname, vendor, product, bcd_device); DBG(DBG_info, "%s: found %s flatbed scanner %s at %s\n", __func__, dev->model->vendor, dev->model->model, dev->file_name.c_str()); @@ -4899,7 +4903,8 @@ static void probe_genesys_devices() DBG_HELPER(dbg); if (is_testing_mode()) { attach_usb_device(get_testing_device_name().c_str(), - get_testing_vendor_id(), get_testing_product_id()); + get_testing_vendor_id(), get_testing_product_id(), + get_testing_bcd_device()); return; } diff --git a/backend/genesys/low.h b/backend/genesys/low.h index 39297bf0e..728c22fa1 100644 --- a/backend/genesys/low.h +++ b/backend/genesys/low.h @@ -170,21 +170,44 @@ namespace genesys { class UsbDeviceEntry { public: + static constexpr std::uint16_t BCD_DEVICE_NOT_SET = 0xffff; UsbDeviceEntry(std::uint16_t vendor_id, std::uint16_t product_id, - const Genesys_Model& model) : - vendor_{vendor_id}, product_{product_id}, model_{model} + const Genesys_Model& model) : + vendor_{vendor_id}, product_{product_id}, + bcd_device_{BCD_DEVICE_NOT_SET}, model_{model} + {} + + UsbDeviceEntry(std::uint16_t vendor_id, std::uint16_t product_id, std::uint16_t bcd_device, + const Genesys_Model& model) : + vendor_{vendor_id}, product_{product_id}, + bcd_device_{bcd_device}, model_{model} {} std::uint16_t vendor_id() const { return vendor_; } std::uint16_t product_id() const { return product_; } + std::uint16_t bcd_device() const { return bcd_device_; } + const Genesys_Model& model() const { return model_; } + bool matches(std::uint16_t vendor_id, std::uint16_t product_id, std::uint16_t bcd_device) + { + if (vendor_ != vendor_id) + return false; + if (product_ != product_id) + return false; + if (bcd_device_ != BCD_DEVICE_NOT_SET && bcd_device_ != bcd_device) + return false; + return true; + } + private: // USB vendor identifier std::uint16_t vendor_; // USB product identifier std::uint16_t product_; + // USB bcdProduct identifier + std::uint16_t bcd_device_; // Scanner model information Genesys_Model model_; }; diff --git a/backend/genesys/test_settings.cpp b/backend/genesys/test_settings.cpp index 425f09cc2..f3287095b 100644 --- a/backend/genesys/test_settings.cpp +++ b/backend/genesys/test_settings.cpp @@ -52,6 +52,7 @@ namespace { bool s_testing_mode = false; std::uint16_t s_vendor_id = 0; std::uint16_t s_product_id = 0; +std::uint16_t s_bcd_device = 0; TestCheckpointCallback s_checkpoint_callback; } // namespace @@ -66,15 +67,17 @@ void disable_testing_mode() s_testing_mode = false; s_vendor_id = 0; s_product_id = 0; - + s_bcd_device = 0; } void enable_testing_mode(std::uint16_t vendor_id, std::uint16_t product_id, + std::uint16_t bcd_device, TestCheckpointCallback checkpoint_callback) { s_testing_mode = true; s_vendor_id = vendor_id; s_product_id = product_id; + s_bcd_device = bcd_device; s_checkpoint_callback = checkpoint_callback; } @@ -88,6 +91,11 @@ std::uint16_t get_testing_product_id() return s_product_id; } +std::uint16_t get_testing_bcd_device() +{ + return s_bcd_device; +} + std::string get_testing_device_name() { std::string name; diff --git a/backend/genesys/test_settings.h b/backend/genesys/test_settings.h index 8ac03e010..38cc3b389 100644 --- a/backend/genesys/test_settings.h +++ b/backend/genesys/test_settings.h @@ -58,9 +58,11 @@ using TestCheckpointCallback = std::function get_all_test_configs() TestConfig config; config.vendor_id = usb_dev.vendor_id(); config.product_id = usb_dev.product_id(); + config.bcd_device = usb_dev.bcd_device(); config.model_name = model.name; config.method = method; config.depth = depth;