blob: d72ae6981f13ec05c10a9f99eef006e4eba4ccc4 [file] [log] [blame] [edit]
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LORGNETTE_USB_USB_DEVICE_H_
#define LORGNETTE_USB_USB_DEVICE_H_
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <utility>
#include <libusb.h>
#include <lorgnette/proto_bindings/lorgnette_service.pb.h>
namespace lorgnette {
using VidPid = std::pair<uint16_t, uint16_t>;
class UsbDevice {
public:
UsbDevice();
UsbDevice(const UsbDevice&) = delete;
UsbDevice& operator=(const UsbDevice&) = delete;
UsbDevice(UsbDevice&&) = default;
UsbDevice& operator=(UsbDevice&&) = default;
virtual ~UsbDevice() = default;
using ScopedConfigDescriptor =
std::unique_ptr<libusb_config_descriptor,
void (*)(libusb_config_descriptor*)>;
// Equivalent of `libusb_get_device_descriptor`.
virtual std::optional<libusb_device_descriptor> GetDeviceDescriptor()
const = 0;
// Equivalent of `libusb_get_config_descriptor`. The returned object will
// clean itself up and must not be passed to `libusb_free_config_descriptor`.
virtual ScopedConfigDescriptor GetConfigDescriptor(uint8_t config) const = 0;
// Equivalent of `libusb_get_string_descriptor_ascii`.
virtual std::optional<std::string> GetStringDescriptor(uint8_t index) = 0;
// Equivalent of `libusb_get_bus_number`.
virtual uint8_t GetBusNumber() const = 0;
// Equivalent of `libusb_get_device_address`.
virtual uint8_t GetDeviceAddress() const = 0;
// Returns `vid_`.
uint16_t GetVid() const;
// Returns `pid_`.
uint16_t GetPid() const;
// Returns a description of this device that can be used for logging.
std::string Description() const;
// Returns the device serial number if available. Returns a blank string if
// the serial number is empty or an error occurs.
std::string GetSerialNumber();
// Constructors can't call virtual functions. This does equivalent setup, but
// can be called after the object is created. Must be called before calling
// the other non-virtual functions.
void Init();
// Returns true if this device contains a printer class interface that
// supports the appropriate IPP-USB protocol.
bool SupportsIppUsb() const;
// Returns a populated ScannerInfo struct as if this device were an eSCL over
// IPP-USB scanner. The returned name will only work if the device actually
// does support eSCL through its IPP-USB interface.
std::optional<ScannerInfo> IppUsbScannerInfo();
// If this device needs to have a backend downloaded with DLC before it will
// be recognized by `sane_get_devices`, then this method will return the ID of
// the required DLC. Otherwise, it will return std::nullopt.
std::optional<std::string> GetNonBundledBackendId() const;
// Setter for `dlc_backend_scanners_`
// Pointer passed in can not be nullptr and needs to outlive this object
void SetDlcBackendScanners(
std::map<VidPid, std::string>* dlc_backend_scanners);
// Returns the current map of VidPid pairs that need DLC for their backend
std::map<VidPid, std::string>* GetDlcBackendScanners();
private:
uint16_t vid_;
uint16_t pid_;
std::string vid_pid_; // Cached copy of formatted VID:PID for logging.
// Map of real scanners that need a DLC backend.
std::map<VidPid, std::string> default_dlc_backend_scanners_;
// Pointer to the map of all scanners that need a DLC backend. Default value
// is set the address of `default_dlc_backend_scanners_`. Not owned.
std::map<VidPid, std::string>* dlc_backend_scanners_;
};
} // namespace lorgnette
#endif // LORGNETTE_USB_USB_DEVICE_H_