blob: e32082d618f94e08b8a22356f1632c7fe84d839a [file] [log] [blame]
// Copyright 2014 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 <iostream> // NOLINT(readability/streams)
#include <memory>
#include <string>
#include <sysexits.h>
#include <base/command_line.h>
#include <base/logging.h>
#include <base/memory/ref_counted.h>
#include <base/values.h>
#include <chromeos/any.h>
#include <chromeos/data_encoding.h>
#include <chromeos/dbus/data_serialization.h>
#include <chromeos/dbus/dbus_method_invoker.h>
#include <chromeos/errors/error.h>
#include <chromeos/variant_dictionary.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/object_proxy.h>
#include <dbus/object_manager.h>
#include <dbus/values_util.h>
#include "buffet/libbuffet/dbus_constants.h"
using namespace buffet::dbus_constants; // NOLINT(build/namespaces)
using chromeos::dbus_utils::CallMethodAndBlock;
using chromeos::dbus_utils::CallMethodAndBlockWithTimeout;
using chromeos::dbus_utils::ExtractMethodCallResults;
using chromeos::VariantDictionary;
using chromeos::ErrorPtr;
namespace {
void usage() {
std::cerr << "Possible commands:" << std::endl;
std::cerr << " " << kManagerTestMethod << " <message>" << std::endl;
std::cerr << " " << kManagerStartDevice << std::endl;
std::cerr << " " << kManagerCheckDeviceRegistered << std::endl;
std::cerr << " " << kManagerGetDeviceInfo << std::endl;
std::cerr << " " << kManagerRegisterDevice
<< " param1 = val1&param2 = val2..." << std::endl;
std::cerr << " " << kManagerAddCommand
<< " '{\"name\":\"command_name\",\"parameters\":{}}'"
<< std::endl;
std::cerr << " " << kManagerUpdateStateMethod
<< " prop_name prop_value" << std::endl;
std::cerr << " " << dbus::kObjectManagerGetManagedObjects << std::endl;
}
class BuffetHelperProxy {
public:
int Init() {
dbus::Bus::Options options;
options.bus_type = dbus::Bus::SYSTEM;
bus_ = new dbus::Bus(options);
manager_proxy_ = bus_->GetObjectProxy(
kServiceName,
dbus::ObjectPath(kManagerServicePath));
root_proxy_ = bus_->GetObjectProxy(
kServiceName,
dbus::ObjectPath(kRootServicePath));
return EX_OK;
}
int CallTestMethod(const CommandLine::StringVector& args) {
std::string message;
if (!args.empty())
message = args.front();
ErrorPtr error;
auto response = CallMethodAndBlock(
manager_proxy_,
kManagerInterface, kManagerTestMethod, &error,
message);
std::string response_message;
if (!response ||
!ExtractMethodCallResults(response.get(), &error, &response_message)) {
std::cout << "Failed to receive a response:"
<< error->GetMessage() << std::endl;
return EX_UNAVAILABLE;
}
std::cout << "Received a response: " << response_message << std::endl;
return EX_OK;
}
int CallManagerStartDevice(const CommandLine::StringVector& args) {
if (!args.empty()) {
std::cerr << "Invalid number of arguments for "
<< "Manager." << kManagerStartDevice << std::endl;
usage();
return EX_USAGE;
}
ErrorPtr error;
auto response = CallMethodAndBlock(
manager_proxy_,
kManagerInterface, kManagerStartDevice, &error);
if (!response || !ExtractMethodCallResults(response.get(), &error)) {
std::cout << "Failed to receive a response:"
<< error->GetMessage() << std::endl;
return EX_UNAVAILABLE;
}
return EX_OK;
}
int CallManagerCheckDeviceRegistered(const CommandLine::StringVector& args) {
if (!args.empty()) {
std::cerr << "Invalid number of arguments for "
<< "Manager." << kManagerCheckDeviceRegistered << std::endl;
usage();
return EX_USAGE;
}
ErrorPtr error;
auto response = CallMethodAndBlock(
manager_proxy_,
kManagerInterface, kManagerCheckDeviceRegistered, &error);
std::string device_id;
if (!response ||
!ExtractMethodCallResults(response.get(), &error, &device_id)) {
std::cout << "Failed to receive a response:"
<< error->GetMessage() << std::endl;
return EX_UNAVAILABLE;
}
std::cout << "Device ID: "
<< (device_id.empty() ? std::string("<unregistered>") : device_id)
<< std::endl;
return EX_OK;
}
int CallManagerGetDeviceInfo(const CommandLine::StringVector& args) {
if (!args.empty()) {
std::cerr << "Invalid number of arguments for "
<< "Manager." << kManagerGetDeviceInfo << std::endl;
usage();
return EX_USAGE;
}
ErrorPtr error;
auto response = CallMethodAndBlock(
manager_proxy_, kManagerInterface, kManagerGetDeviceInfo, &error);
std::string device_info;
if (!response ||
!ExtractMethodCallResults(response.get(), &error, &device_info)) {
std::cout << "Failed to receive a response:"
<< error->GetMessage() << std::endl;
return EX_UNAVAILABLE;
}
std::cout << "Device Info: "
<< (device_info.empty() ? std::string("<unregistered>") : device_info)
<< std::endl;
return EX_OK;
}
int CallManagerRegisterDevice(const CommandLine::StringVector& args) {
if (args.size() > 1) {
std::cerr << "Invalid number of arguments for "
<< "Manager." << kManagerRegisterDevice << std::endl;
usage();
return EX_USAGE;
}
VariantDictionary params;
if (!args.empty()) {
auto key_values = chromeos::data_encoding::WebParamsDecode(args.front());
for (const auto& pair : key_values) {
params.insert(std::make_pair(pair.first, chromeos::Any(pair.second)));
}
}
ErrorPtr error;
static const int timeout_ms = 3000;
auto response = CallMethodAndBlockWithTimeout(
timeout_ms,
manager_proxy_,
kManagerInterface, kManagerRegisterDevice, &error,
params);
std::string device_id;
if (!response ||
!ExtractMethodCallResults(response.get(), &error, &device_id)) {
std::cout << "Failed to receive a response:"
<< error->GetMessage() << std::endl;
return EX_UNAVAILABLE;
}
std::cout << "Device registered: " << device_id << std::endl;
return EX_OK;
}
int CallManagerUpdateState(const CommandLine::StringVector& args) {
if (args.size() != 2) {
std::cerr << "Invalid number of arguments for "
<< "Manager." << kManagerUpdateStateMethod << std::endl;
usage();
return EX_USAGE;
}
ErrorPtr error;
VariantDictionary property_set{{args.front(), args.back()}};
auto response = CallMethodAndBlock(
manager_proxy_,
kManagerInterface, kManagerUpdateStateMethod, &error,
property_set);
if (!response || !ExtractMethodCallResults(response.get(), &error)) {
std::cout << "Failed to receive a response:"
<< error->GetMessage() << std::endl;
return EX_UNAVAILABLE;
}
return EX_OK;
}
int CallManagerAddCommand(const CommandLine::StringVector& args) {
if (args.size() != 1) {
std::cerr << "Invalid number of arguments for "
<< "Manager." << kManagerAddCommand << std::endl;
usage();
return EX_USAGE;
}
ErrorPtr error;
auto response = CallMethodAndBlock(
manager_proxy_,
kManagerInterface, kManagerAddCommand, &error,
args.front());
if (!response || !ExtractMethodCallResults(response.get(), &error)) {
std::cout << "Failed to receive a response:"
<< error->GetMessage() << std::endl;
return EX_UNAVAILABLE;
}
return EX_OK;
}
int CallRootGetManagedObjects(const CommandLine::StringVector& args) {
if (!args.empty()) {
std::cerr << "Invalid number of arguments for "
<< dbus::kObjectManagerGetManagedObjects << std::endl;
usage();
return EX_USAGE;
}
ErrorPtr error;
auto response = CallMethodAndBlock(
manager_proxy_,
dbus::kObjectManagerInterface, dbus::kObjectManagerGetManagedObjects,
&error);
if (!response) {
std::cout << "Failed to receive a response:"
<< error->GetMessage() << std::endl;
return EX_UNAVAILABLE;
}
std::cout << response->ToString() << std::endl;
return EX_OK;
}
private:
scoped_refptr<dbus::Bus> bus_;
dbus::ObjectProxy* manager_proxy_{nullptr};
dbus::ObjectProxy* root_proxy_{nullptr};
};
} // namespace
int main(int argc, char** argv) {
CommandLine::Init(argc, argv);
CommandLine* cl = CommandLine::ForCurrentProcess();
CommandLine::StringVector args = cl->GetArgs();
if (args.empty()) {
usage();
return EX_USAGE;
}
// Pop the command off of the args list.
std::string command = args.front();
args.erase(args.begin());
int err = EX_USAGE;
BuffetHelperProxy helper;
err = helper.Init();
if (err) {
std::cerr << "Error initializing proxies." << std::endl;
return err;
}
if (command.compare(kManagerTestMethod) == 0) {
err = helper.CallTestMethod(args);
} else if (command.compare(kManagerStartDevice) == 0 ||
command.compare("sd") == 0) {
err = helper.CallManagerStartDevice(args);
} else if (command.compare(kManagerCheckDeviceRegistered) == 0 ||
command.compare("cr") == 0) {
err = helper.CallManagerCheckDeviceRegistered(args);
} else if (command.compare(kManagerGetDeviceInfo) == 0 ||
command.compare("di") == 0) {
err = helper.CallManagerGetDeviceInfo(args);
} else if (command.compare(kManagerRegisterDevice) == 0 ||
command.compare("rd") == 0) {
err = helper.CallManagerRegisterDevice(args);
} else if (command.compare(kManagerUpdateStateMethod) == 0 ||
command.compare("us") == 0) {
err = helper.CallManagerUpdateState(args);
} else if (command.compare(kManagerAddCommand) == 0 ||
command.compare("ac") == 0) {
err = helper.CallManagerAddCommand(args);
} else if (command.compare(dbus::kObjectManagerGetManagedObjects) == 0) {
err = helper.CallRootGetManagedObjects(args);
} else {
std::cerr << "Unknown command: " << command << std::endl;
usage();
}
if (err) {
std::cerr << "Done, with errors." << std::endl;
} else {
std::cout << "Done." << std::endl;
}
return err;
}