blob: 59e4fe91930ec73545a49100c74c193e6a014b40 [file] [log] [blame]
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <cstdio>
#include <map>
#include <string>
#include <vector>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/json/json_reader.h>
#include <base/logging.h>
#include <base/optional.h>
#include <base/strings/stringprintf.h>
#include <base/values.h>
#include <brillo/flag_helper.h>
#include <brillo/syslog_logging.h>
#include "device_descriptors.h"
#include "load_config.h"
#include "server.h"
#include "usb_printer.h"
#include "usbip.h"
#include "usbip_constants.h"
#include "value_util.h"
namespace {
constexpr char kUsage[] =
"virtual_usb_printer --descriptors_path=<path> [--record_doc_path=<path>] "
"[--attributes_path=<path>]";
// Create a new UsbDescriptors object using the USB descriptors defined in
// |printer_config|.
UsbDescriptors CreateUsbDescriptors(
const base::DictionaryValue* printer_config) {
UsbDeviceDescriptor device = GetDeviceDescriptor(printer_config);
UsbConfigurationDescriptor configuration =
GetConfigurationDescriptor(printer_config);
UsbDeviceQualifierDescriptor qualifier =
GetDeviceQualifierDescriptor(printer_config);
std::vector<UsbInterfaceDescriptor> interfaces =
GetInterfaceDescriptors(printer_config);
std::map<uint8_t, std::vector<UsbEndpointDescriptor>> endpoint_map =
GetEndpointDescriptorMap(printer_config);
std::vector<std::vector<char>> strings = GetStringDescriptors(printer_config);
std::vector<char> ieee_device_id = GetIEEEDeviceId(printer_config);
return UsbDescriptors(device, configuration, qualifier, strings,
ieee_device_id, interfaces, endpoint_map);
}
} // namespace
int main(int argc, char* argv[]) {
DEFINE_string(descriptors_path, "", "Path to descriptors JSON file");
DEFINE_string(record_doc_path, "", "Path to file to record document to");
DEFINE_string(attributes_path, "", "Path to IPP attributes JSON file");
brillo::FlagHelper::Init(argc, argv, "Virtual USB Printer");
brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderrIfTty);
if (FLAGS_descriptors_path.empty()) {
LOG(ERROR) << kUsage;
return 1;
}
base::Optional<std::string> descriptors_contents =
GetJSONContents(FLAGS_descriptors_path);
if (!descriptors_contents.has_value()) {
LOG(ERROR) << "Failed to load file contents for " << FLAGS_descriptors_path;
return 1;
}
base::JSONReader json_reader;
std::unique_ptr<base::Value> descriptors =
json_reader.Read(*descriptors_contents);
if (descriptors == nullptr) {
LOG(ERROR) << "Failed to parse " << FLAGS_descriptors_path;
return 1;
}
base::DictionaryValue* descriptors_dictionary;
if (!descriptors->GetAsDictionary(&descriptors_dictionary)) {
LOG(ERROR) << "Failed to extract printer configuration as dictionary";
return 1;
}
UsbDescriptors usb_descriptors = CreateUsbDescriptors(descriptors_dictionary);
UsbPrinter printer(usb_descriptors);
if (!FLAGS_record_doc_path.empty() &&
!printer.SetupRecordDocument(FLAGS_record_doc_path)) {
LOG(ERROR) << "Failed to open file: " << FLAGS_record_doc_path;
LOG(ERROR) << "Error code: " << printer.FileError();
return 1;
}
// Load ipp attributes if |FLAGS_attributes_path| is set.
std::unique_ptr<base::Value> attributes;
if (!FLAGS_attributes_path.empty()) {
base::Optional<std::string> attributes_contents =
GetJSONContents(FLAGS_attributes_path);
if (!attributes_contents.has_value()) {
LOG(ERROR) << "Failed to load file contents for "
<< FLAGS_attributes_path;
return 1;
}
attributes = json_reader.Read(*attributes_contents);
if (attributes == nullptr) {
LOG(ERROR) << "Failed to parse " << FLAGS_attributes_path;
return 1;
}
std::vector<IppAttribute> operation_attributes =
GetAttributes(attributes.get(), kOperationAttributes);
std::vector<IppAttribute> printer_attributes =
GetAttributes(attributes.get(), kPrinterAttributes);
std::vector<IppAttribute> job_attributes =
GetAttributes(attributes.get(), kJobAttributes);
std::vector<IppAttribute> unsupported_attributes =
GetAttributes(attributes.get(), kUnsupportedAttributes);
printer.SetOperationAttributes(operation_attributes);
printer.SetPrinterAttributes(printer_attributes);
printer.SetJobAttributes(job_attributes);
printer.SetUnsupportedAttributes(unsupported_attributes);
}
RunServer(printer);
}