blob: 4de32be0832d271827fd28edafaa8e408462c3df [file] [log] [blame]
Darin Petkov63138a92012-02-06 14:09:15 +01001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Masoned0ceb8c2011-06-02 10:05:39 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Deymocddd2d02014-11-10 19:55:35 -08005#include "shill/dbus_adaptor.h"
6
Chris Masone8fe2c7e2011-06-09 15:51:19 -07007#include <map>
Chris Masoned0ceb8c2011-06-02 10:05:39 -07008#include <string>
Chris Masone8fe2c7e2011-06-09 15:51:19 -07009#include <vector>
Chris Masoned0ceb8c2011-06-02 10:05:39 -070010
Eric Shienbrood9a245532012-03-07 14:20:39 -050011#include <base/bind.h>
12#include <base/callback.h>
Chris Masoned0ceb8c2011-06-02 10:05:39 -070013#include <dbus-c++/dbus.h>
14
Chris Masone889666b2011-07-03 12:58:50 -070015#include "shill/accessor_interface.h"
Chris Masone8fe2c7e2011-06-09 15:51:19 -070016#include "shill/error.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070017#include "shill/key_value_store.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070018#include "shill/logging.h"
Chris Masoneb925cc82011-06-22 15:39:57 -070019#include "shill/property_store.h"
Chris Masone8fe2c7e2011-06-09 15:51:19 -070020
Eric Shienbrood9a245532012-03-07 14:20:39 -050021using base::Bind;
22using base::Owned;
Chris Masone8fe2c7e2011-06-09 15:51:19 -070023using std::map;
24using std::string;
25using std::vector;
Chris Masoned0ceb8c2011-06-02 10:05:39 -070026
27namespace shill {
28
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070029namespace Logging {
30static auto kModuleLogScope = ScopeLogger::kDBus;
Paul Stewarta794cd62015-06-16 13:13:10 -070031static string ObjectID(DBusAdaptor* d) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070032 if (d == nullptr)
33 return "(dbus_adaptor)";
34 return d->path();
35}
36}
37
mukesh agrawalcbfb34e2013-04-17 19:33:25 -070038// public static
39const char DBusAdaptor::kNullPath[] = "/";
Chris Masone8fe2c7e2011-06-09 15:51:19 -070040
Paul Stewarta794cd62015-06-16 13:13:10 -070041DBusAdaptor::DBusAdaptor(DBus::Connection* conn, const string& object_path)
Chris Masoned0ceb8c2011-06-02 10:05:39 -070042 : DBus::ObjectAdaptor(*conn, object_path) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070043 SLOG(this, 2) << "DBusAdaptor: " << object_path;
Chris Masoned0ceb8c2011-06-02 10:05:39 -070044}
45
46DBusAdaptor::~DBusAdaptor() {}
47
48// static
Paul Stewarta794cd62015-06-16 13:13:10 -070049bool DBusAdaptor::SetProperty(PropertyStore* store,
50 const string& name,
51 const ::DBus::Variant& value,
52 ::DBus::Error* error) {
mukesh agrawalffa3d042011-10-06 15:26:10 -070053 Error e;
mukesh agrawalbebf1b82013-04-23 15:06:33 -070054 bool ret;
Chris Masone8fe2c7e2011-06-09 15:51:19 -070055
Alex Vakulenko8a532292014-06-16 17:18:44 -070056 if (DBusAdaptor::IsBool(value.signature())) {
mukesh agrawalbebf1b82013-04-23 15:06:33 -070057 ret = store->SetBoolProperty(name, value.reader().get_bool(), &e);
Alex Vakulenko8a532292014-06-16 17:18:44 -070058 } else if (DBusAdaptor::IsByte(value.signature())) {
mukesh agrawalbebf1b82013-04-23 15:06:33 -070059 ret = store->SetUint8Property(name, value.reader().get_byte(), &e);
Alex Vakulenko8a532292014-06-16 17:18:44 -070060 } else if (DBusAdaptor::IsInt16(value.signature())) {
mukesh agrawalbebf1b82013-04-23 15:06:33 -070061 ret = store->SetInt16Property(name, value.reader().get_int16(), &e);
Alex Vakulenko8a532292014-06-16 17:18:44 -070062 } else if (DBusAdaptor::IsInt32(value.signature())) {
mukesh agrawalbebf1b82013-04-23 15:06:33 -070063 ret = store->SetInt32Property(name, value.reader().get_int32(), &e);
Alex Vakulenko8a532292014-06-16 17:18:44 -070064 } else if (DBusAdaptor::IsPath(value.signature())) {
mukesh agrawalbebf1b82013-04-23 15:06:33 -070065 ret = store->SetStringProperty(name, value.reader().get_path(), &e);
Alex Vakulenko8a532292014-06-16 17:18:44 -070066 } else if (DBusAdaptor::IsString(value.signature())) {
mukesh agrawalbebf1b82013-04-23 15:06:33 -070067 ret = store->SetStringProperty(name, value.reader().get_string(), &e);
Alex Vakulenko8a532292014-06-16 17:18:44 -070068 } else if (DBusAdaptor::IsStringmap(value.signature())) {
mukesh agrawalbebf1b82013-04-23 15:06:33 -070069 ret = store->SetStringmapProperty(name,
70 value.operator map<string, string>(),
71 &e);
Alex Vakulenko8a532292014-06-16 17:18:44 -070072 } else if (DBusAdaptor::IsStringmaps(value.signature())) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070073 SLOG(nullptr, 1) << " can't yet handle setting type " << value.signature();
mukesh agrawalbebf1b82013-04-23 15:06:33 -070074 ret = false;
mukesh agrawalffa3d042011-10-06 15:26:10 -070075 e.Populate(Error::kInternalError);
Alex Vakulenko8a532292014-06-16 17:18:44 -070076 } else if (DBusAdaptor::IsStrings(value.signature())) {
mukesh agrawalbebf1b82013-04-23 15:06:33 -070077 ret = store->SetStringsProperty(name, value.operator vector<string>(), &e);
Alex Vakulenko8a532292014-06-16 17:18:44 -070078 } else if (DBusAdaptor::IsUint16(value.signature())) {
mukesh agrawalbebf1b82013-04-23 15:06:33 -070079 ret = store->SetUint16Property(name, value.reader().get_uint16(), &e);
Alex Vakulenko8a532292014-06-16 17:18:44 -070080 } else if (DBusAdaptor::IsUint16s(value.signature())) {
Ben Chan7fab8972014-08-10 17:14:46 -070081 ret =
82 store->SetUint16sProperty(name, value.operator vector<uint16_t>(), &e);
Alex Vakulenko8a532292014-06-16 17:18:44 -070083 } else if (DBusAdaptor::IsUint32(value.signature())) {
mukesh agrawalbebf1b82013-04-23 15:06:33 -070084 ret = store->SetUint32Property(name, value.reader().get_uint32(), &e);
Alex Vakulenko8a532292014-06-16 17:18:44 -070085 } else if (DBusAdaptor::IsUint64(value.signature())) {
mukesh agrawalbebf1b82013-04-23 15:06:33 -070086 ret = store->SetUint64Property(name, value.reader().get_uint64(), &e);
Alex Vakulenko8a532292014-06-16 17:18:44 -070087 } else if (DBusAdaptor::IsKeyValueStore(value.signature())) {
Paul Stewart004b3852015-01-13 15:01:08 -080088 KeyValueStore key_value_store;
89 auto dict = value.operator map<string, DBus::Variant>();
90 DBusAdaptor::ArgsToKeyValueStore(dict, &key_value_store, &e);
91 if (e.IsSuccess()) {
92 ret = store->SetKeyValueStoreProperty(name, key_value_store, &e);
93 } else {
94 ret = false;
95 }
Eric Shienbroodb23d4b92012-02-16 12:32:42 -050096 } else {
Chris Masone27c4aa52011-07-02 13:10:14 -070097 NOTREACHED() << " unknown type: " << value.signature();
mukesh agrawalbebf1b82013-04-23 15:06:33 -070098 ret = false;
mukesh agrawalffa3d042011-10-06 15:26:10 -070099 e.Populate(Error::kInternalError);
Chris Masone27c4aa52011-07-02 13:10:14 -0700100 }
mukesh agrawalffa3d042011-10-06 15:26:10 -0700101
Ben Chancc225ef2014-09-30 13:26:51 -0700102 if (error != nullptr) {
mukesh agrawalffa3d042011-10-06 15:26:10 -0700103 e.ToDBusError(error);
104 }
105
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700106 return ret;
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700107}
108
109// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700110bool DBusAdaptor::GetProperties(const PropertyStore& store,
111 map<string, ::DBus::Variant>* out,
112 ::DBus::Error* /*error*/) {
Chris Masonea8a2c252011-06-27 22:16:30 -0700113 {
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800114 ReadablePropertyConstIterator<bool> it = store.GetBoolPropertiesIter();
mukesh agrawal465331c2012-05-30 11:26:11 -0700115 for ( ; !it.AtEnd(); it.Advance()) {
Darin Petkov4682aa82012-05-31 16:24:11 +0200116 (*out)[it.Key()] = BoolToVariant(it.value());
mukesh agrawal465331c2012-05-30 11:26:11 -0700117 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700118 }
119 {
Ben Chan7fab8972014-08-10 17:14:46 -0700120 ReadablePropertyConstIterator<int16_t> it = store.GetInt16PropertiesIter();
mukesh agrawal465331c2012-05-30 11:26:11 -0700121 for ( ; !it.AtEnd(); it.Advance()) {
Darin Petkov4682aa82012-05-31 16:24:11 +0200122 (*out)[it.Key()] = Int16ToVariant(it.value());
mukesh agrawal465331c2012-05-30 11:26:11 -0700123 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700124 }
125 {
Ben Chan7fab8972014-08-10 17:14:46 -0700126 ReadablePropertyConstIterator<int32_t> it = store.GetInt32PropertiesIter();
mukesh agrawal465331c2012-05-30 11:26:11 -0700127 for ( ; !it.AtEnd(); it.Advance()) {
Darin Petkov4682aa82012-05-31 16:24:11 +0200128 (*out)[it.Key()] = Int32ToVariant(it.value());
mukesh agrawal465331c2012-05-30 11:26:11 -0700129 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700130 }
131 {
Darin Petkov63138a92012-02-06 14:09:15 +0100132 ReadablePropertyConstIterator<KeyValueStore> it =
133 store.GetKeyValueStorePropertiesIter();
mukesh agrawal465331c2012-05-30 11:26:11 -0700134 for ( ; !it.AtEnd(); it.Advance()) {
Darin Petkov4682aa82012-05-31 16:24:11 +0200135 (*out)[it.Key()] = KeyValueStoreToVariant(it.value());
mukesh agrawal465331c2012-05-30 11:26:11 -0700136 }
Darin Petkov63138a92012-02-06 14:09:15 +0100137 }
138 {
mukesh agrawal2366eed2012-03-20 18:21:50 -0700139 ReadablePropertyConstIterator<RpcIdentifiers> it =
140 store.GetRpcIdentifiersPropertiesIter();
141 for ( ; !it.AtEnd(); it.Advance()) {
mukesh agrawal2366eed2012-03-20 18:21:50 -0700142 vector < ::DBus::Path> rpc_identifiers_as_paths;
Paul Stewarta794cd62015-06-16 13:13:10 -0700143 for (const auto& path : it.value()) {
Paul Stewart48231832013-07-17 15:46:19 -0700144 rpc_identifiers_as_paths.push_back(path);
mukesh agrawal2366eed2012-03-20 18:21:50 -0700145 }
146 (*out)[it.Key()] = PathsToVariant(rpc_identifiers_as_paths);
147 }
148 }
149 {
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800150 ReadablePropertyConstIterator<string> it = store.GetStringPropertiesIter();
mukesh agrawal465331c2012-05-30 11:26:11 -0700151 for ( ; !it.AtEnd(); it.Advance()) {
Darin Petkov4682aa82012-05-31 16:24:11 +0200152 (*out)[it.Key()] = StringToVariant(it.value());
mukesh agrawal465331c2012-05-30 11:26:11 -0700153 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700154 }
155 {
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800156 ReadablePropertyConstIterator<Stringmap> it =
157 store.GetStringmapPropertiesIter();
mukesh agrawal465331c2012-05-30 11:26:11 -0700158 for ( ; !it.AtEnd(); it.Advance()) {
Darin Petkov4682aa82012-05-31 16:24:11 +0200159 (*out)[it.Key()]= StringmapToVariant(it.value());
mukesh agrawal465331c2012-05-30 11:26:11 -0700160 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700161 }
162 {
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400163 ReadablePropertyConstIterator<Stringmaps> it =
164 store.GetStringmapsPropertiesIter();
mukesh agrawal465331c2012-05-30 11:26:11 -0700165 for ( ; !it.AtEnd(); it.Advance()) {
Darin Petkov4682aa82012-05-31 16:24:11 +0200166 (*out)[it.Key()]= StringmapsToVariant(it.value());
mukesh agrawal465331c2012-05-30 11:26:11 -0700167 }
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400168 }
169 {
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800170 ReadablePropertyConstIterator<Strings> it =
171 store.GetStringsPropertiesIter();
mukesh agrawal465331c2012-05-30 11:26:11 -0700172 for ( ; !it.AtEnd(); it.Advance()) {
Darin Petkov4682aa82012-05-31 16:24:11 +0200173 (*out)[it.Key()] = StringsToVariant(it.value());
mukesh agrawal465331c2012-05-30 11:26:11 -0700174 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700175 }
176 {
Ben Chan7fab8972014-08-10 17:14:46 -0700177 ReadablePropertyConstIterator<uint8_t> it = store.GetUint8PropertiesIter();
mukesh agrawal465331c2012-05-30 11:26:11 -0700178 for ( ; !it.AtEnd(); it.Advance()) {
Darin Petkov4682aa82012-05-31 16:24:11 +0200179 (*out)[it.Key()] = ByteToVariant(it.value());
mukesh agrawal465331c2012-05-30 11:26:11 -0700180 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700181 }
182 {
Ben Chan7fab8972014-08-10 17:14:46 -0700183 ReadablePropertyConstIterator<uint16_t> it =
184 store.GetUint16PropertiesIter();
mukesh agrawal465331c2012-05-30 11:26:11 -0700185 for ( ; !it.AtEnd(); it.Advance()) {
Darin Petkov4682aa82012-05-31 16:24:11 +0200186 (*out)[it.Key()] = Uint16ToVariant(it.value());
mukesh agrawal465331c2012-05-30 11:26:11 -0700187 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700188 }
189 {
mukesh agrawale7c7e652013-06-18 17:19:39 -0700190 ReadablePropertyConstIterator<Uint16s> it =
191 store.GetUint16sPropertiesIter();
192 for ( ; !it.AtEnd(); it.Advance()) {
193 (*out)[it.Key()] = Uint16sToVariant(it.value());
194 }
195 }
196 {
Ben Chan7fab8972014-08-10 17:14:46 -0700197 ReadablePropertyConstIterator<uint32_t> it =
198 store.GetUint32PropertiesIter();
mukesh agrawal465331c2012-05-30 11:26:11 -0700199 for ( ; !it.AtEnd(); it.Advance()) {
Darin Petkov4682aa82012-05-31 16:24:11 +0200200 (*out)[it.Key()] = Uint32ToVariant(it.value());
mukesh agrawal465331c2012-05-30 11:26:11 -0700201 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700202 }
Jason Glasgowacdc11f2012-03-30 14:12:22 -0400203 {
Ben Chan7fab8972014-08-10 17:14:46 -0700204 ReadablePropertyConstIterator<uint64_t> it =
205 store.GetUint64PropertiesIter();
Paul Stewarte18c33b2012-07-10 20:48:44 -0700206 for ( ; !it.AtEnd(); it.Advance()) {
Paul Stewarte18c33b2012-07-10 20:48:44 -0700207 (*out)[it.Key()] = Uint64ToVariant(it.value());
208 }
209 }
210 {
Jason Glasgowacdc11f2012-03-30 14:12:22 -0400211 ReadablePropertyConstIterator<RpcIdentifier> it =
212 store.GetRpcIdentifierPropertiesIter();
213 for ( ; !it.AtEnd(); it.Advance()) {
Darin Petkov4682aa82012-05-31 16:24:11 +0200214 (*out)[it.Key()] = PathToVariant(it.value());
Jason Glasgowacdc11f2012-03-30 14:12:22 -0400215 }
216 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700217 return true;
218}
219
220// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700221bool DBusAdaptor::ClearProperty(PropertyStore* store,
222 const string& name,
223 ::DBus::Error* error) {
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800224 Error e;
225 store->ClearProperty(name, &e);
226
Ben Chancc225ef2014-09-30 13:26:51 -0700227 if (error != nullptr) {
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800228 e.ToDBusError(error);
229 }
230
231 return e.IsSuccess();
232}
233
234// static
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700235void DBusAdaptor::ArgsToKeyValueStore(
Paul Stewarta794cd62015-06-16 13:13:10 -0700236 const map<string, ::DBus::Variant>& args,
237 KeyValueStore* out,
238 Error* error) { // TODO(quiche): Should be ::DBus::Error?
239 for (const auto& key_value_pair : args) {
Paul Stewart48231832013-07-17 15:46:19 -0700240 string key = key_value_pair.first;
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700241 DBus::type<string> string_type;
242 DBus::type<bool> bool_type;
Ben Chan7fab8972014-08-10 17:14:46 -0700243 DBus::type<int32_t> int32_type;
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700244
Paul Stewart48231832013-07-17 15:46:19 -0700245 if (key_value_pair.second.signature() == bool_type.sig()) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700246 SLOG(nullptr, 5) << "Got bool property " << key;
Paul Stewart48231832013-07-17 15:46:19 -0700247 out->SetBool(key, key_value_pair.second.reader().get_bool());
248 } else if (key_value_pair.second.signature() == int32_type.sig()) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700249 SLOG(nullptr, 5) << "Got int32_t property " << key;
Paul Stewart48231832013-07-17 15:46:19 -0700250 out->SetInt(key, key_value_pair.second.reader().get_int32());
251 } else if (key_value_pair.second.signature() == string_type.sig()) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700252 SLOG(nullptr, 5) << "Got string property " << key;
Paul Stewart48231832013-07-17 15:46:19 -0700253 out->SetString(key, key_value_pair.second.reader().get_string());
Paul Stewartbb833562015-01-21 23:30:46 -0800254 } else if (DBusAdaptor::IsKeyValueStore(
255 key_value_pair.second.signature())) {
256 // Unwrap a recursive KeyValueStore object.
257 KeyValueStore store;
258 Error convert_error;
259 DBusAdaptor::ArgsToKeyValueStore(
260 key_value_pair.second.operator map<string, ::DBus::Variant>(),
261 &store,
262 &convert_error);
263 if (convert_error.IsSuccess()) {
264 out->SetKeyValueStore(key, store);
265 } else {
266 Error::PopulateAndLog(FROM_HERE, error, convert_error.type(),
267 convert_error.message() + " in sub-key " + key);
268 return; // Skip remaining args after error.
269 }
Paul Stewart48231832013-07-17 15:46:19 -0700270 } else if (DBusAdaptor::IsStrings(key_value_pair.second.signature())) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700271 SLOG(nullptr, 5) << "Got strings property " << key;
Paul Stewart48231832013-07-17 15:46:19 -0700272 out->SetStrings(key, key_value_pair.second.operator vector<string>());
Arman Uguray631c7e42013-07-30 16:41:12 -0700273 } else if (DBusAdaptor::IsStringmap(key_value_pair.second.signature())) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700274 SLOG(nullptr, 5) << "Got stringmap property " << key;
Arman Uguray631c7e42013-07-30 16:41:12 -0700275 out->SetStringmap(
276 key, key_value_pair.second.operator map<string, string>());
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700277 } else {
Paul Stewart34f424e2015-01-16 15:30:20 -0800278 Error::PopulateAndLog(FROM_HERE, error, Error::kInternalError,
mukesh agrawal06175d72012-04-23 16:46:01 -0700279 "unsupported type for property " + key);
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800280 return; // Skip remaining args after error.
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700281 }
282 }
283}
284
285// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700286string DBusAdaptor::SanitizePathElement(const string& object_path) {
Paul Stewartf3b38402015-01-16 12:59:03 -0800287 string sanitized_path(object_path);
288 size_t length = sanitized_path.length();
289
290 for (size_t i = 0; i < length; ++i) {
291 char c = sanitized_path[i];
292 // The D-Bus specification
293 // (http://dbus.freedesktop.org/doc/dbus-specification.html) states:
294 // Each element must only contain the ASCII characters "[A-Z][a-z][0-9]_"
295 if (!(c >= 'A' && c <= 'Z') &&
296 !(c >= 'a' && c <= 'z') &&
297 !(c >= '0' && c <= '9') &&
298 c != '_') {
299 sanitized_path[i] = '_';
300 }
301 }
302
303 return sanitized_path;
304}
305
306// static
Chris Masoned0ceb8c2011-06-02 10:05:39 -0700307::DBus::Variant DBusAdaptor::BoolToVariant(bool value) {
308 ::DBus::Variant v;
309 v.writer().append_bool(value);
310 return v;
311}
312
313// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700314::DBus::Variant DBusAdaptor::ByteArraysToVariant(const ByteArrays& value) {
Paul Stewartced6a0b2011-11-08 15:32:04 -0800315 ::DBus::MessageIter writer;
316 ::DBus::Variant v;
317
Gaurav Shah7ad8e532011-11-11 17:14:49 -0800318
319 // We have to use a local because the operator<< needs a reference
320 // to work on (the lhs) but writer() returns by-value. C++ prohibits
321 // initializing non-const references from a temporary.
322 // So:
323 // v.writer() << value;
324 // would NOT automagically promote the returned value of v.writer() to
325 // a non-const reference (if you think about it, that's almost always not what
326 // you'd want. see: http://gcc.gnu.org/ml/gcc-help/2006-04/msg00075.html).
327 //
328 // One could consider changing writer() to return a reference, but then it
329 // changes writer() semantics as it can not be a const reference. writer()
330 // currently doesn't modify the original object on which it's called.
Paul Stewartced6a0b2011-11-08 15:32:04 -0800331 writer = v.writer();
332 writer << value;
333 return v;
334}
335
336// static
Ben Chan7fab8972014-08-10 17:14:46 -0700337::DBus::Variant DBusAdaptor::ByteToVariant(uint8_t value) {
Chris Masoned0ceb8c2011-06-02 10:05:39 -0700338 ::DBus::Variant v;
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700339 v.writer().append_byte(value);
Chris Masoned0ceb8c2011-06-02 10:05:39 -0700340 return v;
341}
342
343// static
Ben Chan7fab8972014-08-10 17:14:46 -0700344::DBus::Variant DBusAdaptor::Int16ToVariant(int16_t value) {
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700345 ::DBus::Variant v;
346 v.writer().append_int16(value);
347 return v;
348}
349
350// static
Ben Chan7fab8972014-08-10 17:14:46 -0700351::DBus::Variant DBusAdaptor::Int32ToVariant(int32_t value) {
Chris Masoned0ceb8c2011-06-02 10:05:39 -0700352 ::DBus::Variant v;
353 v.writer().append_int32(value);
354 return v;
355}
356
357// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700358::DBus::Variant DBusAdaptor::PathToVariant(const ::DBus::Path& value) {
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700359 ::DBus::Variant v;
360 v.writer().append_path(value.c_str());
361 return v;
362}
363
364// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700365::DBus::Variant DBusAdaptor::PathsToVariant(const vector<::DBus::Path>& value) {
mukesh agrawal32399322011-09-01 10:53:43 -0700366 ::DBus::MessageIter writer;
367 ::DBus::Variant v;
368
Gaurav Shah7ad8e532011-11-11 17:14:49 -0800369 // See note above on why we need to use a local.
mukesh agrawal32399322011-09-01 10:53:43 -0700370 writer = v.writer();
371 writer << value;
372 return v;
373}
374
375// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700376::DBus::Variant DBusAdaptor::StringToVariant(const string& value) {
Chris Masoned0ceb8c2011-06-02 10:05:39 -0700377 ::DBus::Variant v;
378 v.writer().append_string(value.c_str());
379 return v;
380}
381
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700382// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700383::DBus::Variant DBusAdaptor::StringmapToVariant(const Stringmap& value) {
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700384 ::DBus::Variant v;
385 ::DBus::MessageIter writer = v.writer();
386 writer << value;
387 return v;
388}
389
390// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700391::DBus::Variant DBusAdaptor::StringmapsToVariant(const Stringmaps& value) {
Chris Masoneb925cc82011-06-22 15:39:57 -0700392 ::DBus::Variant v;
393 ::DBus::MessageIter writer = v.writer();
394 writer << value;
395 return v;
396}
397
398// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700399::DBus::Variant DBusAdaptor::StringsToVariant(const Strings& value) {
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700400 ::DBus::Variant v;
401 ::DBus::MessageIter writer = v.writer();
402 writer << value;
403 return v;
404}
405
406// static
Darin Petkov63138a92012-02-06 14:09:15 +0100407::DBus::Variant DBusAdaptor::KeyValueStoreToVariant(
Paul Stewarta794cd62015-06-16 13:13:10 -0700408 const KeyValueStore& value) {
Darin Petkov25665aa2012-05-21 14:08:12 +0200409 DBusPropertiesMap props;
410 DBusProperties::ConvertKeyValueStoreToMap(value, &props);
Chris Masone889666b2011-07-03 12:58:50 -0700411 ::DBus::Variant v;
412 ::DBus::MessageIter writer = v.writer();
Eric Shienbroodb23d4b92012-02-16 12:32:42 -0500413 writer << props;
Chris Masone889666b2011-07-03 12:58:50 -0700414 return v;
415}
416
417// static
Ben Chan7fab8972014-08-10 17:14:46 -0700418::DBus::Variant DBusAdaptor::Uint16ToVariant(uint16_t value) {
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700419 ::DBus::Variant v;
420 v.writer().append_uint16(value);
421 return v;
422}
423
424// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700425::DBus::Variant DBusAdaptor::Uint16sToVariant(const Uint16s& value) {
mukesh agrawale7c7e652013-06-18 17:19:39 -0700426 ::DBus::Variant v;
427 ::DBus::MessageIter writer = v.writer();
428 writer << value;
429 return v;
430}
431
432// static
Ben Chan7fab8972014-08-10 17:14:46 -0700433::DBus::Variant DBusAdaptor::Uint32ToVariant(uint32_t value) {
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700434 ::DBus::Variant v;
435 v.writer().append_uint32(value);
436 return v;
437}
438
439// static
Ben Chan7fab8972014-08-10 17:14:46 -0700440::DBus::Variant DBusAdaptor::Uint64ToVariant(uint64_t value) {
Paul Stewarte18c33b2012-07-10 20:48:44 -0700441 ::DBus::Variant v;
442 v.writer().append_uint64(value);
443 return v;
444}
445
446// static
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700447bool DBusAdaptor::IsBool(::DBus::Signature signature) {
448 return signature == ::DBus::type<bool>::sig();
449}
450
451// static
452bool DBusAdaptor::IsByte(::DBus::Signature signature) {
Ben Chan7fab8972014-08-10 17:14:46 -0700453 return signature == ::DBus::type<uint8_t>::sig();
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700454}
455
456// static
Paul Stewartced6a0b2011-11-08 15:32:04 -0800457bool DBusAdaptor::IsByteArrays(::DBus::Signature signature) {
mukesh agrawal97ede7b2013-11-21 15:28:14 -0800458 return signature == ::DBus::type<ByteArrays>::sig();
Paul Stewartced6a0b2011-11-08 15:32:04 -0800459}
460
461// static
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700462bool DBusAdaptor::IsInt16(::DBus::Signature signature) {
Ben Chan7fab8972014-08-10 17:14:46 -0700463 return signature == ::DBus::type<int16_t>::sig();
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700464}
465
466// static
467bool DBusAdaptor::IsInt32(::DBus::Signature signature) {
Ben Chan7fab8972014-08-10 17:14:46 -0700468 return signature == ::DBus::type<int32_t>::sig();
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700469}
470
471// static
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700472bool DBusAdaptor::IsPath(::DBus::Signature signature) {
Ben Chane2ee5e02014-09-19 19:29:42 -0700473 return signature == ::DBus::type<::DBus::Path>::sig();
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700474}
475
476// static
mukesh agrawal2366eed2012-03-20 18:21:50 -0700477bool DBusAdaptor::IsPaths(::DBus::Signature signature) {
Ben Chane2ee5e02014-09-19 19:29:42 -0700478 return signature == ::DBus::type<vector<::DBus::Path>>::sig();
mukesh agrawal32399322011-09-01 10:53:43 -0700479}
480
481// static
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700482bool DBusAdaptor::IsString(::DBus::Signature signature) {
483 return signature == ::DBus::type<string>::sig();
484}
485
486// static
487bool DBusAdaptor::IsStringmap(::DBus::Signature signature) {
mukesh agrawal97ede7b2013-11-21 15:28:14 -0800488 return signature == ::DBus::type<Stringmap>::sig();
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700489}
490
491// static
Chris Masone27c4aa52011-07-02 13:10:14 -0700492bool DBusAdaptor::IsStringmaps(::DBus::Signature signature) {
mukesh agrawal97ede7b2013-11-21 15:28:14 -0800493 return signature == ::DBus::type<Stringmaps>::sig();
Chris Masone27c4aa52011-07-02 13:10:14 -0700494}
495
496// static
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700497bool DBusAdaptor::IsStrings(::DBus::Signature signature) {
mukesh agrawal97ede7b2013-11-21 15:28:14 -0800498 return signature == ::DBus::type<Strings>::sig();
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700499}
500
501// static
502bool DBusAdaptor::IsUint16(::DBus::Signature signature) {
Ben Chan7fab8972014-08-10 17:14:46 -0700503 return signature == ::DBus::type<uint16_t>::sig();
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700504}
505
506// static
mukesh agrawale7c7e652013-06-18 17:19:39 -0700507bool DBusAdaptor::IsUint16s(::DBus::Signature signature) {
mukesh agrawal97ede7b2013-11-21 15:28:14 -0800508 return signature == ::DBus::type<Uint16s>::sig();
mukesh agrawale7c7e652013-06-18 17:19:39 -0700509}
510
511// static
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700512bool DBusAdaptor::IsUint32(::DBus::Signature signature) {
Ben Chan7fab8972014-08-10 17:14:46 -0700513 return signature == ::DBus::type<uint32_t>::sig();
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700514}
515
Darin Petkove5bc2cb2011-12-07 14:47:32 +0100516// static
Paul Stewarte18c33b2012-07-10 20:48:44 -0700517bool DBusAdaptor::IsUint64(::DBus::Signature signature) {
Ben Chan7fab8972014-08-10 17:14:46 -0700518 return signature == ::DBus::type<uint64_t>::sig();
Paul Stewarte18c33b2012-07-10 20:48:44 -0700519}
520
521// static
Eric Shienbroodb23d4b92012-02-16 12:32:42 -0500522bool DBusAdaptor::IsKeyValueStore(::DBus::Signature signature) {
Ben Chane2ee5e02014-09-19 19:29:42 -0700523 return signature == ::DBus::type<map<string, ::DBus::Variant>>::sig();
Eric Shienbroodb23d4b92012-02-16 12:32:42 -0500524}
525
Paul Stewarta794cd62015-06-16 13:13:10 -0700526void DBusAdaptor::DeferReply(const DBus::Tag* tag) {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500527 return_later(tag);
Darin Petkove5bc2cb2011-12-07 14:47:32 +0100528}
529
Paul Stewarta794cd62015-06-16 13:13:10 -0700530void DBusAdaptor::ReplyNow(const DBus::Tag* tag) {
531 Continuation* cont = find_continuation(tag);
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700532 CHECK(cont) << "Failed to find continuation.";
Eric Shienbrood9a245532012-03-07 14:20:39 -0500533 return_now(cont);
Darin Petkove5bc2cb2011-12-07 14:47:32 +0100534}
535
Christopher Wiley0d9cf0c2013-02-19 19:24:57 -0800536template <typename T>
Paul Stewarta794cd62015-06-16 13:13:10 -0700537void DBusAdaptor::TypedReplyNow(const DBus::Tag* tag, const T& value) {
538 Continuation* cont = find_continuation(tag);
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700539 CHECK(cont) << "Failed to find continuation.";
Christopher Wiley0d9cf0c2013-02-19 19:24:57 -0800540 cont->writer() << value;
541 return_now(cont);
542}
543
Paul Stewarta794cd62015-06-16 13:13:10 -0700544void DBusAdaptor::ReplyNowWithError(const DBus::Tag* tag,
545 const DBus::Error& error) {
546 Continuation* cont = find_continuation(tag);
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700547 CHECK(cont) << "Failed to find continuation.";
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700548 SLOG(this, 1) << "Returning error: (" << error.name() << ": "
Prathmesh Prabhu51a4f932014-08-13 13:13:27 -0700549 << error.message() << ")";
Eric Shienbrood9a245532012-03-07 14:20:39 -0500550 return_error(cont, error);
Darin Petkove5bc2cb2011-12-07 14:47:32 +0100551}
552
Eric Shienbrood9a245532012-03-07 14:20:39 -0500553ResultCallback DBusAdaptor::GetMethodReplyCallback(
Paul Stewarta794cd62015-06-16 13:13:10 -0700554 const DBus::Tag* tag) {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500555 return Bind(&DBusAdaptor::MethodReplyCallback, AsWeakPtr(), Owned(tag));
556}
557
Christopher Wiley0d9cf0c2013-02-19 19:24:57 -0800558ResultStringCallback DBusAdaptor::GetStringMethodReplyCallback(
Paul Stewarta794cd62015-06-16 13:13:10 -0700559 const DBus::Tag* tag) {
Christopher Wiley0d9cf0c2013-02-19 19:24:57 -0800560 return Bind(&DBusAdaptor::StringMethodReplyCallback, AsWeakPtr(), Owned(tag));
561}
562
563ResultBoolCallback DBusAdaptor::GetBoolMethodReplyCallback(
Paul Stewarta794cd62015-06-16 13:13:10 -0700564 const DBus::Tag* tag) {
Christopher Wiley0d9cf0c2013-02-19 19:24:57 -0800565 return Bind(&DBusAdaptor::BoolMethodReplyCallback, AsWeakPtr(), Owned(tag));
566}
567
568template<typename T>
Paul Stewarta794cd62015-06-16 13:13:10 -0700569void DBusAdaptor::TypedMethodReplyCallback(const DBus::Tag* tag,
570 const Error& error,
571 const T& returned) {
Christopher Wiley0d9cf0c2013-02-19 19:24:57 -0800572 if (error.IsFailure()) {
573 DBus::Error dberror;
574 error.ToDBusError(&dberror);
575 ReplyNowWithError(tag, dberror);
576 } else {
577 TypedReplyNow(tag, returned);
578 }
579}
580
Paul Stewarta794cd62015-06-16 13:13:10 -0700581void DBusAdaptor::ReturnResultOrDefer(const DBus::Tag* tag,
582 const Error& error,
583 DBus::Error* dberror) {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500584 if (error.IsOngoing()) {
585 DeferReply(tag);
586 } else if (error.IsFailure()) {
587 error.ToDBusError(dberror);
Darin Petkove5bc2cb2011-12-07 14:47:32 +0100588 }
589}
590
Paul Stewarta794cd62015-06-16 13:13:10 -0700591void DBusAdaptor::MethodReplyCallback(const DBus::Tag* tag,
592 const Error& error) {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500593 if (error.IsFailure()) {
594 DBus::Error dberror;
595 error.ToDBusError(&dberror);
596 ReplyNowWithError(tag, dberror);
597 } else {
598 ReplyNow(tag);
Darin Petkove5bc2cb2011-12-07 14:47:32 +0100599 }
600}
601
Paul Stewarta794cd62015-06-16 13:13:10 -0700602void DBusAdaptor::StringMethodReplyCallback(const DBus::Tag* tag,
603 const Error& error,
604 const string& returned) {
Christopher Wiley0d9cf0c2013-02-19 19:24:57 -0800605 TypedMethodReplyCallback(tag, error, returned);
606}
607
Paul Stewarta794cd62015-06-16 13:13:10 -0700608void DBusAdaptor::BoolMethodReplyCallback(const DBus::Tag* tag,
609 const Error& error,
Christopher Wiley0d9cf0c2013-02-19 19:24:57 -0800610 bool returned) {
611 TypedMethodReplyCallback(tag, error, returned);
612}
613
Chris Masoned0ceb8c2011-06-02 10:05:39 -0700614} // namespace shill