blob: c567716824d4d1082efc28c397c484939d9436db [file] [log] [blame]
Ben Chanfad4a0b2012-04-18 15:49:59 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkove0a312e2011-07-20 13:45:28 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/dbus_properties.h"
6
Ben Chan0a3a3a52013-07-10 11:34:07 -07007#include <dbus/dbus.h>
Jason Glasgow9c09e362012-04-18 15:16:29 -04008
Christopher Wileyb691efd2012-08-09 13:51:51 -07009#include "shill/logging.h"
Darin Petkovceb68172011-07-29 14:47:48 -070010
Darin Petkov25665aa2012-05-21 14:08:12 +020011using std::map;
Jason Glasgow9c09e362012-04-18 15:16:29 -040012using std::string;
13using std::vector;
14
Darin Petkove0a312e2011-07-20 13:45:28 -070015namespace shill {
16
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070017namespace Logging {
Paul Stewarta794cd62015-06-16 13:13:10 -070018static string ObjectID(DBusProperties* d) { return "(dbus_properties)"; }
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070019}
20
Ben Chan0a3a3a52013-07-10 11:34:07 -070021namespace {
22
23template <typename ValueType>
Paul Stewarta794cd62015-06-16 13:13:10 -070024bool GetValue(const DBusPropertiesMap& properties,
25 const string& key,
26 ValueType* value) {
Ben Chan0a3a3a52013-07-10 11:34:07 -070027 CHECK(value);
28
29 DBusPropertiesMap::const_iterator it = properties.find(key);
30 if (it == properties.end()) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070031 SLOG(DBus, nullptr, 2) << "Key '" << key << "' not found.";
Ben Chan0a3a3a52013-07-10 11:34:07 -070032 return false;
33 }
34
35 string actual_type = it->second.signature();
36 string expected_type = DBus::type<ValueType>::sig();
37 if (actual_type != expected_type) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070038 SLOG(DBus, nullptr, 2) << "Key '" << key << "' type mismatch (expected '"
39 << expected_type << "', actual '" << actual_type
40 << "').";
Ben Chan0a3a3a52013-07-10 11:34:07 -070041 return false;
42 }
43
44 *value = it->second.operator ValueType();
45 return true;
46}
47
48} // namespace
49
Darin Petkove0a312e2011-07-20 13:45:28 -070050// static
Paul Stewarta794cd62015-06-16 13:13:10 -070051bool DBusProperties::GetBool(const DBusPropertiesMap& properties,
52 const string& key,
53 bool* value) {
Ben Chan0a3a3a52013-07-10 11:34:07 -070054 return GetValue<bool>(properties, key, value);
55}
56
57// static
Peter Qiu34a9bb32015-07-09 11:08:28 -070058bool DBusProperties::GetByteArrays(const DBusPropertiesMap& properties,
59 const string& key,
60 vector<vector<uint8_t>>* value) {
61 return GetValue<vector<vector<uint8_t>>>(properties, key, value);
62}
63
64// static
Paul Stewarta794cd62015-06-16 13:13:10 -070065bool DBusProperties::GetDBusPropertiesMap(const DBusPropertiesMap& properties,
66 const string& key,
67 DBusPropertiesMap* value) {
Ben Chan0a3a3a52013-07-10 11:34:07 -070068 return GetValue<DBusPropertiesMap>(properties, key, value);
69}
70
71// static
Paul Stewarta794cd62015-06-16 13:13:10 -070072bool DBusProperties::GetDouble(const DBusPropertiesMap& properties,
73 const string& key,
74 double* value) {
Ben Chan0a3a3a52013-07-10 11:34:07 -070075 return GetValue<double>(properties, key, value);
76}
77
78// static
Paul Stewarta794cd62015-06-16 13:13:10 -070079bool DBusProperties::GetInt16(const DBusPropertiesMap& properties,
80 const string& key,
81 int16_t* value) {
Ben Chan7fab8972014-08-10 17:14:46 -070082 return GetValue<int16_t>(properties, key, value);
Eric Shienbrood7fce52c2012-04-13 19:11:02 -040083}
84
85// static
Paul Stewarta794cd62015-06-16 13:13:10 -070086bool DBusProperties::GetInt32(const DBusPropertiesMap& properties,
87 const string& key,
88 int32_t* value) {
Ben Chan7fab8972014-08-10 17:14:46 -070089 return GetValue<int32_t>(properties, key, value);
Ben Chan0a3a3a52013-07-10 11:34:07 -070090}
91
92// static
Paul Stewarta794cd62015-06-16 13:13:10 -070093bool DBusProperties::GetInt64(const DBusPropertiesMap& properties,
94 const string& key,
95 int64_t* value) {
Ben Chan7fab8972014-08-10 17:14:46 -070096 return GetValue<int64_t>(properties, key, value);
Darin Petkove0a312e2011-07-20 13:45:28 -070097}
98
99// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700100bool DBusProperties::GetObjectPath(const DBusPropertiesMap& properties,
101 const string& key,
102 DBus::Path* value) {
Ben Chan0a3a3a52013-07-10 11:34:07 -0700103 return GetValue<DBus::Path>(properties, key, value);
Nathan Williamse9840802012-04-18 18:47:40 -0400104}
105
106// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700107bool DBusProperties::GetString(const DBusPropertiesMap& properties,
108 const string& key,
109 string* value) {
Ben Chan0a3a3a52013-07-10 11:34:07 -0700110 return GetValue<string>(properties, key, value);
Darin Petkovceb68172011-07-29 14:47:48 -0700111}
112
113// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700114bool DBusProperties::GetStringmap(const DBusPropertiesMap& properties,
115 const string& key,
116 map<string, string>* value) {
Arman Uguray631c7e42013-07-30 16:41:12 -0700117 return GetValue<map<string, string>>(properties, key, value);
118}
119
120// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700121bool DBusProperties::GetStrings(const DBusPropertiesMap& properties,
122 const string& key,
123 vector<string>* value) {
Ben Chan0a3a3a52013-07-10 11:34:07 -0700124 return GetValue<vector<string>>(properties, key, value);
125}
126
127// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700128bool DBusProperties::GetUint8(const DBusPropertiesMap& properties,
129 const string& key,
130 uint8_t* value) {
Ben Chan7fab8972014-08-10 17:14:46 -0700131 return GetValue<uint8_t>(properties, key, value);
Jason Glasgow9c09e362012-04-18 15:16:29 -0400132}
133
134// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700135bool DBusProperties::GetUint16(const DBusPropertiesMap& properties,
136 const string& key,
137 uint16_t* value) {
Ben Chan7fab8972014-08-10 17:14:46 -0700138 return GetValue<uint16_t>(properties, key, value);
Darin Petkove0a312e2011-07-20 13:45:28 -0700139}
140
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400141// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700142bool DBusProperties::GetUint32(const DBusPropertiesMap& properties,
143 const string& key,
144 uint32_t* value) {
Ben Chan7fab8972014-08-10 17:14:46 -0700145 return GetValue<uint32_t>(properties, key, value);
Ben Chan0a3a3a52013-07-10 11:34:07 -0700146}
147
148// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700149bool DBusProperties::GetUint64(const DBusPropertiesMap& properties,
150 const string& key,
151 uint64_t* value) {
Ben Chan7fab8972014-08-10 17:14:46 -0700152 return GetValue<uint64_t>(properties, key, value);
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400153}
154
Gary Morain610977f2012-05-04 16:03:52 -0700155// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700156bool DBusProperties::GetRpcIdentifiers(const DBusPropertiesMap& properties,
157 const string& key,
158 RpcIdentifiers* value) {
Ben Chan0a3a3a52013-07-10 11:34:07 -0700159 vector<DBus::Path> paths;
160 if (GetValue<vector<DBus::Path>>(properties, key, &paths)) {
161 ConvertPathsToRpcIdentifiers(paths, value);
162 return true;
Darin Petkove4b27022012-05-16 13:28:50 +0200163 }
Ben Chan0a3a3a52013-07-10 11:34:07 -0700164 return false;
Darin Petkove4b27022012-05-16 13:28:50 +0200165}
166
167// static
Peter Qiu34a9bb32015-07-09 11:08:28 -0700168bool DBusProperties::GetUint8s(const DBusPropertiesMap& properties,
169 const string& key,
170 vector<uint8_t>* value) {
171 return GetValue<vector<uint8_t>>(properties, key, value);
172}
173
174// static
175bool DBusProperties::GetUint32s(const DBusPropertiesMap& properties,
176 const string& key,
177 vector<uint32_t>* value) {
178 return GetValue<vector<uint32_t>>(properties, key, value);
179}
180
181// static
Darin Petkov9893d9c2012-05-17 15:27:31 -0700182void DBusProperties::ConvertPathsToRpcIdentifiers(
Paul Stewarta794cd62015-06-16 13:13:10 -0700183 const vector<DBus::Path>& dbus_paths, RpcIdentifiers* rpc_identifiers) {
Darin Petkov25665aa2012-05-21 14:08:12 +0200184 CHECK(rpc_identifiers);
Ben Chan0a3a3a52013-07-10 11:34:07 -0700185 rpc_identifiers->assign(dbus_paths.begin(), dbus_paths.end());
Darin Petkov9893d9c2012-05-17 15:27:31 -0700186}
187
188// static
Darin Petkov25665aa2012-05-21 14:08:12 +0200189void DBusProperties::ConvertKeyValueStoreToMap(
Paul Stewarta794cd62015-06-16 13:13:10 -0700190 const KeyValueStore& store, DBusPropertiesMap* properties) {
Darin Petkov25665aa2012-05-21 14:08:12 +0200191 CHECK(properties);
192 properties->clear();
Peter Qiud31fb582015-07-15 14:33:32 -0700193 for (const auto& key_value_pair : store.properties()) {
194 if (key_value_pair.second.GetType() == typeid(string)) {
195 (*properties)[key_value_pair.first].writer()
196 .append_string(key_value_pair.second.Get<string>().c_str());
197 } else if (key_value_pair.second.GetType() == typeid(Stringmap)) {
198 DBus::MessageIter writer = (*properties)[key_value_pair.first].writer();
199 writer << key_value_pair.second.Get<Stringmap>();
200 } else if (key_value_pair.second.GetType() == typeid(Strings)) {
201 DBus::MessageIter writer = (*properties)[key_value_pair.first].writer();
202 writer << key_value_pair.second.Get<Strings>();
203 } else if (key_value_pair.second.GetType() == typeid(bool)) { // NOLINT
204 (*properties)[key_value_pair.first].writer()
205 .append_bool(key_value_pair.second.Get<bool>());
206 } else if (key_value_pair.second.GetType() == typeid(int32_t)) {
207 (*properties)[key_value_pair.first].writer()
208 .append_int32(key_value_pair.second.Get<int32_t>());
209 } else if (key_value_pair.second.GetType() == typeid(int16_t)) {
210 (*properties)[key_value_pair.first].writer()
211 .append_int16(key_value_pair.second.Get<int16_t>());
212 } else if (key_value_pair.second.GetType() == typeid(uint32_t)) {
213 (*properties)[key_value_pair.first].writer()
214 .append_uint32(key_value_pair.second.Get<uint32_t>());
215 } else if (key_value_pair.second.GetType() == typeid(uint16_t)) {
216 (*properties)[key_value_pair.first].writer()
217 .append_uint16(key_value_pair.second.Get<uint16_t>());
Peter Qiu937fafc2015-07-21 15:34:59 -0700218 } else if (key_value_pair.second.GetType() == typeid(uint8_t)) {
219 (*properties)[key_value_pair.first].writer()
220 .append_byte(key_value_pair.second.Get<uint8_t>());
Peter Qiud31fb582015-07-15 14:33:32 -0700221 } else if (key_value_pair.second.GetType() == typeid(vector<uint8_t>)) {
222 DBus::MessageIter writer = (*properties)[key_value_pair.first].writer();
223 writer << key_value_pair.second.Get<vector<uint8_t>>();
224 } else if (key_value_pair.second.GetType() == typeid(vector<uint32_t>)) {
225 DBus::MessageIter writer = (*properties)[key_value_pair.first].writer();
226 writer << key_value_pair.second.Get<vector<uint32_t>>();
227 } else if (key_value_pair.second.GetType() ==
228 typeid(vector<vector<uint8_t>>)) {
229 DBus::MessageIter writer = (*properties)[key_value_pair.first].writer();
230 writer << key_value_pair.second.Get<vector<vector<uint8_t>>>();
231 } else if (key_value_pair.second.GetType() == typeid(KeyValueStore)) {
232 DBusPropertiesMap props;
233 ConvertKeyValueStoreToMap(key_value_pair.second.Get<KeyValueStore>(),
234 &props);
235 DBus::MessageIter writer = (*properties)[key_value_pair.first].writer();
236 writer << props;
237 } else if (key_value_pair.second.GetType() == typeid(dbus::ObjectPath)) {
238 (*properties)[key_value_pair.first].writer()
239 .append_path(
240 key_value_pair.second.Get<dbus::ObjectPath>().value().c_str());
241 }
Peter Qiu34a9bb32015-07-09 11:08:28 -0700242 }
243}
244
245// static
246void DBusProperties::ConvertMapToKeyValueStore(
247 const DBusPropertiesMap& properties,
248 KeyValueStore* store,
249 Error* error) { // TODO(quiche): Should be ::DBus::Error?
250 for (const auto& key_value_pair : properties) {
251 string key = key_value_pair.first;
252
253 if (key_value_pair.second.signature() == ::DBus::type<bool>::sig()) {
254 SLOG(DBus, nullptr, 5) << "Got bool property " << key;
255 store->SetBool(key, key_value_pair.second.reader().get_bool());
256 } else if (key_value_pair.second.signature() ==
257 ::DBus::type<vector<vector<uint8_t>>>::sig()) {
258 SLOG(DBus, nullptr, 5) << "Got byte_arrays property " << key;
259 store->SetByteArrays(
260 key, key_value_pair.second.operator vector<vector<uint8_t>>());
261 } else if (key_value_pair.second.signature() ==
262 ::DBus::type<int32_t>::sig()) {
263 SLOG(DBus, nullptr, 5) << "Got int32_t property " << key;
264 store->SetInt(key, key_value_pair.second.reader().get_int32());
265 } else if (key_value_pair.second.signature() ==
266 ::DBus::type<int16_t>::sig()) {
267 SLOG(DBus, nullptr, 5) << "Got int16_t property " << key;
268 store->SetInt16(key, key_value_pair.second.reader().get_int16());
269 } else if (key_value_pair.second.signature() ==
270 ::DBus::type<map<string, ::DBus::Variant>>::sig()) {
271 SLOG(DBus, nullptr, 5) << "Got variant map property " << key;
272 // Unwrap a recursive KeyValueStore object.
273 KeyValueStore convert_store;
274 Error convert_error;
275 ConvertMapToKeyValueStore(
276 key_value_pair.second.operator map<string, ::DBus::Variant>(),
277 &convert_store,
278 &convert_error);
279 if (convert_error.IsSuccess()) {
280 store->SetKeyValueStore(key, convert_store);
281 } else {
282 Error::PopulateAndLog(FROM_HERE, error, convert_error.type(),
283 convert_error.message() + " in sub-key " + key);
284 return; // Skip remaining args after error.
285 }
286 } else if (key_value_pair.second.signature() ==
287 ::DBus::type<::DBus::Path>::sig()) {
288 SLOG(DBus, nullptr, 5) << "Got Path property " << key;
289 store->SetRpcIdentifier(key, key_value_pair.second.reader().get_path());
290 } else if (key_value_pair.second.signature() ==
291 ::DBus::type<string>::sig()) {
292 SLOG(DBus, nullptr, 5) << "Got string property " << key;
293 store->SetString(key, key_value_pair.second.reader().get_string());
294 } else if (key_value_pair.second.signature() ==
295 ::DBus::type<Strings>::sig()) {
296 SLOG(DBus, nullptr, 5) << "Got strings property " << key;
297 store->SetStrings(key, key_value_pair.second.operator vector<string>());
298 } else if (key_value_pair.second.signature() ==
299 ::DBus::type<Stringmap>::sig()) {
300 SLOG(DBus, nullptr, 5) << "Got stringmap property " << key;
301 store->SetStringmap(
302 key, key_value_pair.second.operator map<string, string>());
303 } else if (key_value_pair.second.signature() ==
304 ::DBus::type<uint32_t>::sig()) {
305 SLOG(DBus, nullptr, 5) << "Got uint32_t property " << key;
306 store->SetUint(key, key_value_pair.second.reader().get_uint32());
307 } else if (key_value_pair.second.signature() ==
308 ::DBus::type<uint16_t>::sig()) {
309 SLOG(DBus, nullptr, 5) << "Got uint16_t property " << key;
310 store->SetUint16(key, key_value_pair.second.reader().get_uint16());
311 } else if (key_value_pair.second.signature() ==
Peter Qiu937fafc2015-07-21 15:34:59 -0700312 ::DBus::type<uint8_t>::sig()) {
313 SLOG(DBus, nullptr, 5) << "Got uint8_t property " << key;
314 store->SetUint8(key, key_value_pair.second.reader().get_byte());
315 } else if (key_value_pair.second.signature() ==
Peter Qiu34a9bb32015-07-09 11:08:28 -0700316 ::DBus::type<vector<uint8_t>>::sig()) {
317 SLOG(DBus, nullptr, 5) << "Got vector<uint8_t> property " << key;
318 store->SetUint8s(key, key_value_pair.second.operator vector<uint8_t>());
319 } else if (key_value_pair.second.signature() ==
320 ::DBus::type<vector<uint32_t>>::sig()) {
321 SLOG(DBus, nullptr, 5) << "Got vector<uint32_t> property " << key;
322 store->SetUint32s(key, key_value_pair.second.operator vector<uint32_t>());
323 } else {
324 Error::PopulateAndLog(FROM_HERE, error, Error::kInternalError,
325 "unsupported type for property " + key);
326 return; // Skip remaining args after error.
327 }
328 }
Darin Petkov25665aa2012-05-21 14:08:12 +0200329}
330
331// static
Paul Stewarta794cd62015-06-16 13:13:10 -0700332string DBusProperties::KeysToString(const DBusPropertiesMap& properties) {
Ben Chan0a3a3a52013-07-10 11:34:07 -0700333 string keys;
Paul Stewarta794cd62015-06-16 13:13:10 -0700334 for (const auto& key_value_pair : properties) {
Gary Morain610977f2012-05-04 16:03:52 -0700335 keys.append(" ");
Ben Chan0a3a3a52013-07-10 11:34:07 -0700336 keys.append(key_value_pair.first);
Gary Morain610977f2012-05-04 16:03:52 -0700337 }
338 return keys;
339}
340
Darin Petkove0a312e2011-07-20 13:45:28 -0700341} // namespace shill