blob: e32082d618f94e08b8a22356f1632c7fe84d839a [file] [log] [blame]
Chris Sosa45d9f102014-03-24 11:18:54 -07001// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Vakulenkoaf23b322014-05-08 16:25:45 -07005#include <iostream> // NOLINT(readability/streams)
Alex Vakulenko7a1dc0b2014-08-15 11:45:46 -07006#include <memory>
Chris Sosa45d9f102014-03-24 11:18:54 -07007#include <string>
Christopher Wiley48e37282014-05-08 14:43:58 -07008#include <sysexits.h>
Chris Sosa45d9f102014-03-24 11:18:54 -07009
Chris Sosaababc5c2014-04-09 15:42:01 -070010#include <base/command_line.h>
Chris Sosa45d9f102014-03-24 11:18:54 -070011#include <base/logging.h>
Christopher Wiley48e37282014-05-08 14:43:58 -070012#include <base/memory/ref_counted.h>
Alex Vakulenko3cb466c2014-04-15 11:36:32 -070013#include <base/values.h>
Alex Vakulenkoa9044342014-08-23 19:31:27 -070014#include <chromeos/any.h>
Alex Vakulenkoe4879a22014-08-20 15:47:36 -070015#include <chromeos/data_encoding.h>
Alex Vakulenko63cd5fa2014-08-27 08:04:22 -070016#include <chromeos/dbus/data_serialization.h>
Alex Vakulenko07216fe2014-09-19 15:31:09 -070017#include <chromeos/dbus/dbus_method_invoker.h>
18#include <chromeos/errors/error.h>
Alex Vakulenko576c9792014-09-22 16:49:45 -070019#include <chromeos/variant_dictionary.h>
Chris Sosa45d9f102014-03-24 11:18:54 -070020#include <dbus/bus.h>
Christopher Wileya4915c42014-03-27 14:45:37 -070021#include <dbus/message.h>
Christopher Wiley48e37282014-05-08 14:43:58 -070022#include <dbus/object_proxy.h>
Christopher Wileyadb901d2014-05-07 09:58:45 -070023#include <dbus/object_manager.h>
Alex Vakulenko3cb466c2014-04-15 11:36:32 -070024#include <dbus/values_util.h>
Chris Sosa45d9f102014-03-24 11:18:54 -070025
Alex Vakulenko89d9d5e2014-09-12 10:27:23 -070026#include "buffet/libbuffet/dbus_constants.h"
Chris Sosa45d9f102014-03-24 11:18:54 -070027
Alex Vakulenko33797062014-05-12 15:55:25 -070028using namespace buffet::dbus_constants; // NOLINT(build/namespaces)
Chris Sosa45d9f102014-03-24 11:18:54 -070029
Alex Vakulenko07216fe2014-09-19 15:31:09 -070030using chromeos::dbus_utils::CallMethodAndBlock;
31using chromeos::dbus_utils::CallMethodAndBlockWithTimeout;
Alex Vakulenko07216fe2014-09-19 15:31:09 -070032using chromeos::dbus_utils::ExtractMethodCallResults;
Alex Vakulenko576c9792014-09-22 16:49:45 -070033using chromeos::VariantDictionary;
Alex Vakulenko07216fe2014-09-19 15:31:09 -070034using chromeos::ErrorPtr;
35
Chris Sosa45d9f102014-03-24 11:18:54 -070036namespace {
37
Christopher Wileya4915c42014-03-27 14:45:37 -070038void usage() {
39 std::cerr << "Possible commands:" << std::endl;
Alex Vakulenko7a1dc0b2014-08-15 11:45:46 -070040 std::cerr << " " << kManagerTestMethod << " <message>" << std::endl;
Anton Muhin86d67fe2014-10-01 18:06:54 +040041 std::cerr << " " << kManagerStartDevice << std::endl;
Alex Vakulenko3cb466c2014-04-15 11:36:32 -070042 std::cerr << " " << kManagerCheckDeviceRegistered << std::endl;
43 std::cerr << " " << kManagerGetDeviceInfo << std::endl;
Anton Muhinbeb1c5b2014-10-16 18:59:57 +040044 std::cerr << " " << kManagerRegisterDevice
Alex Vakulenko3cb466c2014-04-15 11:36:32 -070045 << " param1 = val1&param2 = val2..." << std::endl;
Alex Vakulenko665c8852014-09-11 16:57:24 -070046 std::cerr << " " << kManagerAddCommand
47 << " '{\"name\":\"command_name\",\"parameters\":{}}'"
48 << std::endl;
Alex Vakulenko07216fe2014-09-19 15:31:09 -070049 std::cerr << " " << kManagerUpdateStateMethod
50 << " prop_name prop_value" << std::endl;
Christopher Wileyadb901d2014-05-07 09:58:45 -070051 std::cerr << " " << dbus::kObjectManagerGetManagedObjects << std::endl;
Christopher Wileya4915c42014-03-27 14:45:37 -070052}
53
Christopher Wiley48e37282014-05-08 14:43:58 -070054class BuffetHelperProxy {
55 public:
56 int Init() {
57 dbus::Bus::Options options;
58 options.bus_type = dbus::Bus::SYSTEM;
59 bus_ = new dbus::Bus(options);
60 manager_proxy_ = bus_->GetObjectProxy(
61 kServiceName,
62 dbus::ObjectPath(kManagerServicePath));
Christopher Wileyadb901d2014-05-07 09:58:45 -070063 root_proxy_ = bus_->GetObjectProxy(
64 kServiceName,
65 dbus::ObjectPath(kRootServicePath));
Christopher Wiley48e37282014-05-08 14:43:58 -070066 return EX_OK;
Christopher Wileya4915c42014-03-27 14:45:37 -070067 }
68
Christopher Wiley48e37282014-05-08 14:43:58 -070069 int CallTestMethod(const CommandLine::StringVector& args) {
Alex Vakulenko7a1dc0b2014-08-15 11:45:46 -070070 std::string message;
71 if (!args.empty())
72 message = args.front();
73
Alex Vakulenko07216fe2014-09-19 15:31:09 -070074 ErrorPtr error;
75 auto response = CallMethodAndBlock(
76 manager_proxy_,
77 kManagerInterface, kManagerTestMethod, &error,
78 message);
79 std::string response_message;
80 if (!response ||
81 !ExtractMethodCallResults(response.get(), &error, &response_message)) {
82 std::cout << "Failed to receive a response:"
83 << error->GetMessage() << std::endl;
Christopher Wiley48e37282014-05-08 14:43:58 -070084 return EX_UNAVAILABLE;
85 }
Alex Vakulenko07216fe2014-09-19 15:31:09 -070086
Alex Vakulenko7a1dc0b2014-08-15 11:45:46 -070087 std::cout << "Received a response: " << response_message << std::endl;
Christopher Wiley48e37282014-05-08 14:43:58 -070088 return EX_OK;
89 }
90
Anton Muhin86d67fe2014-10-01 18:06:54 +040091 int CallManagerStartDevice(const CommandLine::StringVector& args) {
92 if (!args.empty()) {
93 std::cerr << "Invalid number of arguments for "
94 << "Manager." << kManagerStartDevice << std::endl;
95 usage();
96 return EX_USAGE;
97 }
98
99 ErrorPtr error;
100 auto response = CallMethodAndBlock(
101 manager_proxy_,
102 kManagerInterface, kManagerStartDevice, &error);
103 if (!response || !ExtractMethodCallResults(response.get(), &error)) {
104 std::cout << "Failed to receive a response:"
105 << error->GetMessage() << std::endl;
106 return EX_UNAVAILABLE;
107 }
108 return EX_OK;
109 }
110
Christopher Wiley48e37282014-05-08 14:43:58 -0700111 int CallManagerCheckDeviceRegistered(const CommandLine::StringVector& args) {
Alex Vakulenko3cb466c2014-04-15 11:36:32 -0700112 if (!args.empty()) {
Christopher Wileya4915c42014-03-27 14:45:37 -0700113 std::cerr << "Invalid number of arguments for "
Christopher Wiley48e37282014-05-08 14:43:58 -0700114 << "Manager." << kManagerCheckDeviceRegistered << std::endl;
Alex Vakulenko3cb466c2014-04-15 11:36:32 -0700115 usage();
116 return EX_USAGE;
117 }
Christopher Wiley48e37282014-05-08 14:43:58 -0700118
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700119 ErrorPtr error;
120 auto response = CallMethodAndBlock(
121 manager_proxy_,
122 kManagerInterface, kManagerCheckDeviceRegistered, &error);
Christopher Wiley48e37282014-05-08 14:43:58 -0700123 std::string device_id;
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700124 if (!response ||
125 !ExtractMethodCallResults(response.get(), &error, &device_id)) {
126 std::cout << "Failed to receive a response:"
127 << error->GetMessage() << std::endl;
128 return EX_UNAVAILABLE;
Christopher Wiley48e37282014-05-08 14:43:58 -0700129 }
130
131 std::cout << "Device ID: "
132 << (device_id.empty() ? std::string("<unregistered>") : device_id)
133 << std::endl;
134 return EX_OK;
135 }
136
137 int CallManagerGetDeviceInfo(const CommandLine::StringVector& args) {
Alex Vakulenko3cb466c2014-04-15 11:36:32 -0700138 if (!args.empty()) {
139 std::cerr << "Invalid number of arguments for "
Christopher Wiley48e37282014-05-08 14:43:58 -0700140 << "Manager." << kManagerGetDeviceInfo << std::endl;
Alex Vakulenko3cb466c2014-04-15 11:36:32 -0700141 usage();
142 return EX_USAGE;
143 }
Christopher Wiley48e37282014-05-08 14:43:58 -0700144
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700145 ErrorPtr error;
146 auto response = CallMethodAndBlock(
147 manager_proxy_, kManagerInterface, kManagerGetDeviceInfo, &error);
Christopher Wiley48e37282014-05-08 14:43:58 -0700148 std::string device_info;
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700149 if (!response ||
150 !ExtractMethodCallResults(response.get(), &error, &device_info)) {
151 std::cout << "Failed to receive a response:"
152 << error->GetMessage() << std::endl;
153 return EX_UNAVAILABLE;
Christopher Wiley48e37282014-05-08 14:43:58 -0700154 }
155
156 std::cout << "Device Info: "
157 << (device_info.empty() ? std::string("<unregistered>") : device_info)
158 << std::endl;
159 return EX_OK;
160 }
161
Anton Muhinbeb1c5b2014-10-16 18:59:57 +0400162 int CallManagerRegisterDevice(const CommandLine::StringVector& args) {
Alex Vakulenko3cb466c2014-04-15 11:36:32 -0700163 if (args.size() > 1) {
164 std::cerr << "Invalid number of arguments for "
Anton Muhinbeb1c5b2014-10-16 18:59:57 +0400165 << "Manager." << kManagerRegisterDevice << std::endl;
Christopher Wileya4915c42014-03-27 14:45:37 -0700166 usage();
Chris Sosaababc5c2014-04-09 15:42:01 -0700167 return EX_USAGE;
Christopher Wileya4915c42014-03-27 14:45:37 -0700168 }
Alex Vakulenko3cb466c2014-04-15 11:36:32 -0700169
Alex Vakulenko576c9792014-09-22 16:49:45 -0700170 VariantDictionary params;
Alex Vakulenko3cb466c2014-04-15 11:36:32 -0700171 if (!args.empty()) {
Alex Vakulenkoe4879a22014-08-20 15:47:36 -0700172 auto key_values = chromeos::data_encoding::WebParamsDecode(args.front());
Alex Vakulenkoa0424dd2014-06-13 16:10:17 -0700173 for (const auto& pair : key_values) {
Alex Vakulenkoa9044342014-08-23 19:31:27 -0700174 params.insert(std::make_pair(pair.first, chromeos::Any(pair.second)));
Alex Vakulenko3cb466c2014-04-15 11:36:32 -0700175 }
176 }
177
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700178 ErrorPtr error;
Christopher Wiley48e37282014-05-08 14:43:58 -0700179 static const int timeout_ms = 3000;
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700180 auto response = CallMethodAndBlockWithTimeout(
181 timeout_ms,
182 manager_proxy_,
Anton Muhinbeb1c5b2014-10-16 18:59:57 +0400183 kManagerInterface, kManagerRegisterDevice, &error,
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700184 params);
Christopher Wiley48e37282014-05-08 14:43:58 -0700185 std::string device_id;
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700186 if (!response ||
187 !ExtractMethodCallResults(response.get(), &error, &device_id)) {
188 std::cout << "Failed to receive a response:"
189 << error->GetMessage() << std::endl;
190 return EX_UNAVAILABLE;
Christopher Wiley48e37282014-05-08 14:43:58 -0700191 }
192
Anton Muhinbeb1c5b2014-10-16 18:59:57 +0400193 std::cout << "Device registered: " << device_id << std::endl;
Christopher Wiley48e37282014-05-08 14:43:58 -0700194 return EX_OK;
195 }
196
197 int CallManagerUpdateState(const CommandLine::StringVector& args) {
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700198 if (args.size() != 2) {
Christopher Wileya4915c42014-03-27 14:45:37 -0700199 std::cerr << "Invalid number of arguments for "
Alex Vakulenko3cb466c2014-04-15 11:36:32 -0700200 << "Manager." << kManagerUpdateStateMethod << std::endl;
Christopher Wileya4915c42014-03-27 14:45:37 -0700201 usage();
Chris Sosaababc5c2014-04-09 15:42:01 -0700202 return EX_USAGE;
Christopher Wileya4915c42014-03-27 14:45:37 -0700203 }
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700204
205 ErrorPtr error;
Alex Vakulenko576c9792014-09-22 16:49:45 -0700206 VariantDictionary property_set{{args.front(), args.back()}};
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700207 auto response = CallMethodAndBlock(
208 manager_proxy_,
209 kManagerInterface, kManagerUpdateStateMethod, &error,
210 property_set);
211 if (!response || !ExtractMethodCallResults(response.get(), &error)) {
212 std::cout << "Failed to receive a response:"
213 << error->GetMessage() << std::endl;
Christopher Wiley48e37282014-05-08 14:43:58 -0700214 return EX_UNAVAILABLE;
215 }
216 return EX_OK;
217 }
218
Alex Vakulenko665c8852014-09-11 16:57:24 -0700219 int CallManagerAddCommand(const CommandLine::StringVector& args) {
220 if (args.size() != 1) {
221 std::cerr << "Invalid number of arguments for "
222 << "Manager." << kManagerAddCommand << std::endl;
223 usage();
224 return EX_USAGE;
225 }
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700226
227 ErrorPtr error;
228 auto response = CallMethodAndBlock(
229 manager_proxy_,
230 kManagerInterface, kManagerAddCommand, &error,
231 args.front());
232 if (!response || !ExtractMethodCallResults(response.get(), &error)) {
233 std::cout << "Failed to receive a response:"
234 << error->GetMessage() << std::endl;
Alex Vakulenko665c8852014-09-11 16:57:24 -0700235 return EX_UNAVAILABLE;
236 }
237 return EX_OK;
238 }
239
Christopher Wileyadb901d2014-05-07 09:58:45 -0700240 int CallRootGetManagedObjects(const CommandLine::StringVector& args) {
241 if (!args.empty()) {
242 std::cerr << "Invalid number of arguments for "
243 << dbus::kObjectManagerGetManagedObjects << std::endl;
244 usage();
245 return EX_USAGE;
246 }
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700247
248 ErrorPtr error;
249 auto response = CallMethodAndBlock(
250 manager_proxy_,
251 dbus::kObjectManagerInterface, dbus::kObjectManagerGetManagedObjects,
252 &error);
Christopher Wileyadb901d2014-05-07 09:58:45 -0700253 if (!response) {
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700254 std::cout << "Failed to receive a response:"
255 << error->GetMessage() << std::endl;
Christopher Wileyadb901d2014-05-07 09:58:45 -0700256 return EX_UNAVAILABLE;
257 }
258 std::cout << response->ToString() << std::endl;
259 return EX_OK;
260 }
261
Christopher Wiley48e37282014-05-08 14:43:58 -0700262 private:
263 scoped_refptr<dbus::Bus> bus_;
Alex Vakulenkoa0424dd2014-06-13 16:10:17 -0700264 dbus::ObjectProxy* manager_proxy_{nullptr};
265 dbus::ObjectProxy* root_proxy_{nullptr};
Christopher Wiley48e37282014-05-08 14:43:58 -0700266};
267
Alex Vakulenko33797062014-05-12 15:55:25 -0700268} // namespace
Christopher Wiley48e37282014-05-08 14:43:58 -0700269
270int main(int argc, char** argv) {
271 CommandLine::Init(argc, argv);
272 CommandLine* cl = CommandLine::ForCurrentProcess();
273 CommandLine::StringVector args = cl->GetArgs();
274 if (args.empty()) {
Christopher Wileya4915c42014-03-27 14:45:37 -0700275 usage();
Chris Sosaababc5c2014-04-09 15:42:01 -0700276 return EX_USAGE;
Christopher Wileya4915c42014-03-27 14:45:37 -0700277 }
278
Christopher Wiley48e37282014-05-08 14:43:58 -0700279 // Pop the command off of the args list.
280 std::string command = args.front();
281 args.erase(args.begin());
282 int err = EX_USAGE;
283 BuffetHelperProxy helper;
284 err = helper.Init();
285 if (err) {
286 std::cerr << "Error initializing proxies." << std::endl;
287 return err;
Christopher Wileya4915c42014-03-27 14:45:37 -0700288 }
289
Christopher Wiley48e37282014-05-08 14:43:58 -0700290 if (command.compare(kManagerTestMethod) == 0) {
291 err = helper.CallTestMethod(args);
Anton Muhin86d67fe2014-10-01 18:06:54 +0400292 } else if (command.compare(kManagerStartDevice) == 0 ||
293 command.compare("sd") == 0) {
294 err = helper.CallManagerStartDevice(args);
Christopher Wiley48e37282014-05-08 14:43:58 -0700295 } else if (command.compare(kManagerCheckDeviceRegistered) == 0 ||
296 command.compare("cr") == 0) {
297 err = helper.CallManagerCheckDeviceRegistered(args);
298 } else if (command.compare(kManagerGetDeviceInfo) == 0 ||
299 command.compare("di") == 0) {
300 err = helper.CallManagerGetDeviceInfo(args);
Anton Muhinbeb1c5b2014-10-16 18:59:57 +0400301 } else if (command.compare(kManagerRegisterDevice) == 0 ||
302 command.compare("rd") == 0) {
303 err = helper.CallManagerRegisterDevice(args);
Christopher Wiley48e37282014-05-08 14:43:58 -0700304 } else if (command.compare(kManagerUpdateStateMethod) == 0 ||
305 command.compare("us") == 0) {
306 err = helper.CallManagerUpdateState(args);
Alex Vakulenko665c8852014-09-11 16:57:24 -0700307 } else if (command.compare(kManagerAddCommand) == 0 ||
308 command.compare("ac") == 0) {
309 err = helper.CallManagerAddCommand(args);
Christopher Wileyadb901d2014-05-07 09:58:45 -0700310 } else if (command.compare(dbus::kObjectManagerGetManagedObjects) == 0) {
311 err = helper.CallRootGetManagedObjects(args);
Christopher Wiley48e37282014-05-08 14:43:58 -0700312 } else {
313 std::cerr << "Unknown command: " << command << std::endl;
314 usage();
315 }
Chris Sosa45d9f102014-03-24 11:18:54 -0700316
Christopher Wiley48e37282014-05-08 14:43:58 -0700317 if (err) {
318 std::cerr << "Done, with errors." << std::endl;
319 } else {
320 std::cout << "Done." << std::endl;
321 }
322 return err;
323}