blob: dba2f4dacb48d779994abab4b6d340a12b33a576 [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>
#include <string>
#include <base/command_line.h>
#include <base/logging.h>
#include <base/memory/scoped_ptr.h>
#include <base/values.h>
#include <dbus/bus.h>
#include <dbus/object_proxy.h>
#include <dbus/message.h>
#include <sysexits.h>
#include <dbus/values_util.h>
#include "buffet/dbus_constants.h"
#include "buffet/dbus_manager.h"
#include "buffet/data_encoding.h"
using namespace buffet::dbus_constants;
namespace {
static const int default_timeout_ms = 1000;
dbus::ObjectProxy* GetBuffetDBusProxy(dbus::Bus *bus,
const std::string& object_path) {
return bus->GetObjectProxy(
buffet::dbus_constants::kServiceName,
dbus::ObjectPath(object_path));
}
bool CallTestMethod(dbus::ObjectProxy* proxy) {
dbus::MethodCall method_call(buffet::dbus_constants::kRootInterface,
buffet::dbus_constants::kRootTestMethod);
scoped_ptr<dbus::Response> response(
proxy->CallMethodAndBlock(&method_call, default_timeout_ms));
if (!response) {
std::cout << "Failed to receive a response." << std::endl;
return false;
}
std::cout << "Received a response." << std::endl;
return true;
}
bool CallManagerCheckDeviceRegistered(dbus::ObjectProxy* proxy) {
dbus::MethodCall method_call(
buffet::dbus_constants::kManagerInterface,
buffet::dbus_constants::kManagerCheckDeviceRegistered);
scoped_ptr<dbus::Response> response(
proxy->CallMethodAndBlock(&method_call, default_timeout_ms));
if (!response) {
std::cout << "Failed to receive a response." << std::endl;
return false;
}
dbus::MessageReader reader(response.get());
std::string device_id;
if (!reader.PopString(&device_id)) {
std::cout << "No device ID in response." << std::endl;
return false;
}
std::cout << "Device ID: "
<< (device_id.empty() ? std::string("<unregistered>") : device_id)
<< std::endl;
return true;
}
bool CallManagerGetDeviceInfo(dbus::ObjectProxy* proxy) {
dbus::MethodCall method_call(
buffet::dbus_constants::kManagerInterface,
buffet::dbus_constants::kManagerGetDeviceInfo);
scoped_ptr<dbus::Response> response(
proxy->CallMethodAndBlock(&method_call, default_timeout_ms));
if (!response) {
std::cout << "Failed to receive a response." << std::endl;
return false;
}
dbus::MessageReader reader(response.get());
std::string device_info;
if (!reader.PopString(&device_info)) {
std::cout << "No device info in response." << std::endl;
return false;
}
std::cout << "Device Info: "
<< (device_info.empty() ? std::string("<unregistered>") : device_info)
<< std::endl;
return true;
}
bool CallManagerStartRegisterDevice(
dbus::ObjectProxy* proxy,
const std::map<std::string, std::shared_ptr<base::Value>>& params) {
dbus::MethodCall method_call(
buffet::dbus_constants::kManagerInterface,
buffet::dbus_constants::kManagerStartRegisterDevice);
dbus::MessageWriter writer(&method_call);
dbus::MessageWriter dict_writer(nullptr);
writer.OpenArray("{sv}", &dict_writer);
for (auto&& pair : params) {
dbus::MessageWriter dict_entry_writer(nullptr);
dict_writer.OpenDictEntry(&dict_entry_writer);
dict_entry_writer.AppendString(pair.first);
dbus::AppendBasicTypeValueDataAsVariant(&dict_entry_writer,
*pair.second.get());
dict_writer.CloseContainer(&dict_entry_writer);
}
writer.CloseContainer(&dict_writer);
static const int timeout_ms = 3000;
scoped_ptr<dbus::Response> response(
proxy->CallMethodAndBlock(&method_call, timeout_ms));
if (!response) {
std::cout << "Failed to receive a response." << std::endl;
return false;
}
dbus::MessageReader reader(response.get());
std::string info;
if (!reader.PopString(&info)) {
std::cout << "No valid response." << std::endl;
return false;
}
std::cout << "Registration started: " << info << std::endl;
return true;
}
bool CallManagerFinishRegisterDevice(dbus::ObjectProxy* proxy,
const std::string& user_auth_code) {
dbus::MethodCall method_call(
buffet::dbus_constants::kManagerInterface,
buffet::dbus_constants::kManagerFinishRegisterDevice);
dbus::MessageWriter writer(&method_call);
writer.AppendString(user_auth_code);
static const int timeout_ms = 10000;
scoped_ptr<dbus::Response> response(
proxy->CallMethodAndBlock(&method_call, timeout_ms));
if (!response) {
std::cout << "Failed to receive a response." << std::endl;
return false;
}
dbus::MessageReader reader(response.get());
std::string device_id;
if (!reader.PopString(&device_id)) {
std::cout << "No device ID in response." << std::endl;
return false;
}
std::cout << "Device ID is "
<< (device_id.empty() ? std::string("<unregistered>") : device_id)
<< std::endl;
return true;
}
bool CallManagerUpdateState(dbus::ObjectProxy* proxy,
const std::string& json_blob) {
dbus::MethodCall method_call(
buffet::dbus_constants::kManagerInterface,
buffet::dbus_constants::kManagerUpdateStateMethod);
dbus::MessageWriter writer(&method_call);
writer.AppendString(json_blob);
scoped_ptr<dbus::Response> response(
proxy->CallMethodAndBlock(&method_call, default_timeout_ms));
if (!response) {
std::cout << "Failed to receive a response." << std::endl;
return false;
}
return true;
}
void usage() {
std::cerr << "Possible commands:" << std::endl;
std::cerr << " " << kRootTestMethod << std::endl;
std::cerr << " " << kManagerCheckDeviceRegistered << std::endl;
std::cerr << " " << kManagerGetDeviceInfo << std::endl;
std::cerr << " " << kManagerStartRegisterDevice
<< " param1 = val1&param2 = val2..." << std::endl;
std::cerr << " " << kManagerFinishRegisterDevice
<< " device_id" << std::endl;
std::cerr << " " << kManagerUpdateStateMethod << std::endl;
}
} // namespace
int main(int argc, char** argv) {
CommandLine::Init(argc, argv);
CommandLine* cl = CommandLine::ForCurrentProcess();
dbus::Bus::Options options;
options.bus_type = dbus::Bus::SYSTEM;
scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));
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());
bool success = false;
if (command.compare(kRootTestMethod) == 0) {
auto proxy = GetBuffetDBusProxy(
bus, buffet::dbus_constants::kRootServicePath);
success = CallTestMethod(proxy);
} else if (command.compare(kManagerCheckDeviceRegistered) == 0 ||
command.compare("cr") == 0) {
if (!args.empty()) {
std::cerr << "Invalid number of arguments for "
<< "Manager." << kManagerCheckDeviceRegistered << std::endl;
usage();
return EX_USAGE;
}
auto proxy = GetBuffetDBusProxy(
bus, buffet::dbus_constants::kManagerServicePath);
success = CallManagerCheckDeviceRegistered(proxy);
} else if (command.compare(kManagerGetDeviceInfo) == 0 ||
command.compare("di") == 0) {
if (!args.empty()) {
std::cerr << "Invalid number of arguments for "
<< "Manager." << kManagerGetDeviceInfo << std::endl;
usage();
return EX_USAGE;
}
auto proxy = GetBuffetDBusProxy(
bus, buffet::dbus_constants::kManagerServicePath);
success = CallManagerGetDeviceInfo(proxy);
} else if (command.compare(kManagerStartRegisterDevice) == 0 ||
command.compare("sr") == 0) {
if (args.size() > 1) {
std::cerr << "Invalid number of arguments for "
<< "Manager." << kManagerStartRegisterDevice << std::endl;
usage();
return EX_USAGE;
}
auto proxy = GetBuffetDBusProxy(
bus, buffet::dbus_constants::kManagerServicePath);
std::map<std::string, std::shared_ptr<base::Value>> params;
if (!args.empty()) {
auto key_values = chromeos::data_encoding::WebParamsDecode(args.front());
for (auto&& pair : key_values) {
params.insert(std::make_pair(
pair.first, std::shared_ptr<base::Value>(
base::Value::CreateStringValue(pair.second))));
}
}
success = CallManagerStartRegisterDevice(proxy, params);
} else if (command.compare(kManagerFinishRegisterDevice) == 0 ||
command.compare("fr") == 0) {
if (args.size() > 1) {
std::cerr << "Invalid number of arguments for "
<< "Manager." << kManagerFinishRegisterDevice << std::endl;
usage();
return EX_USAGE;
}
auto proxy = GetBuffetDBusProxy(
bus, buffet::dbus_constants::kManagerServicePath);
success = CallManagerFinishRegisterDevice(
proxy, !args.empty() ? args.front() : std::string());
} else if (command.compare(kManagerUpdateStateMethod) == 0 ||
command.compare("us") == 0) {
if (args.size() != 1) {
std::cerr << "Invalid number of arguments for "
<< "Manager." << kManagerUpdateStateMethod << std::endl;
usage();
return EX_USAGE;
}
auto proxy = GetBuffetDBusProxy(
bus, buffet::dbus_constants::kManagerServicePath);
success = CallManagerUpdateState(proxy, args.front());
} else {
std::cerr << "Unknown command: " << command << std::endl;
usage();
return EX_USAGE;
}
if (success) {
std::cout << "Done." << std::endl;
return EX_OK;
}
std::cerr << "Done, with errors." << std::endl;
return 1;
}