| // 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¶m2 = 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; |
| } |