blob: 084de411a335aebef595609dbcb20799fb2c13e1 [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
Chris Masone8fe2c7e2011-06-09 15:51:19 -07005#include <map>
Chris Masoned0ceb8c2011-06-02 10:05:39 -07006#include <string>
Chris Masone8fe2c7e2011-06-09 15:51:19 -07007#include <vector>
Chris Masoned0ceb8c2011-06-02 10:05:39 -07008
Chris Masone8fe2c7e2011-06-09 15:51:19 -07009#include <base/logging.h>
Chris Masoned0ceb8c2011-06-02 10:05:39 -070010#include <dbus-c++/dbus.h>
11
Chris Masone889666b2011-07-03 12:58:50 -070012#include "shill/accessor_interface.h"
Chris Masoned0ceb8c2011-06-02 10:05:39 -070013#include "shill/dbus_adaptor.h"
Chris Masone8fe2c7e2011-06-09 15:51:19 -070014#include "shill/error.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070015#include "shill/key_value_store.h"
Chris Masoneb925cc82011-06-22 15:39:57 -070016#include "shill/property_store.h"
Chris Masone8fe2c7e2011-06-09 15:51:19 -070017
18using std::map;
19using std::string;
20using std::vector;
Chris Masoned0ceb8c2011-06-02 10:05:39 -070021
22namespace shill {
23
Chris Masone8fe2c7e2011-06-09 15:51:19 -070024// static
Paul Stewartced6a0b2011-11-08 15:32:04 -080025const char DBusAdaptor::kByteArraysSig[] = "aay";
26// static
mukesh agrawal2366eed2012-03-20 18:21:50 -070027const char DBusAdaptor::kPathsSig[] = "ao";
mukesh agrawal32399322011-09-01 10:53:43 -070028// static
Chris Masone8fe2c7e2011-06-09 15:51:19 -070029const char DBusAdaptor::kStringmapSig[] = "a{ss}";
30// static
Chris Masone27c4aa52011-07-02 13:10:14 -070031const char DBusAdaptor::kStringmapsSig[] = "aa{ss}";
32// static
Chris Masone8fe2c7e2011-06-09 15:51:19 -070033const char DBusAdaptor::kStringsSig[] = "as";
34
35DBusAdaptor::DBusAdaptor(DBus::Connection* conn, const string &object_path)
Chris Masoned0ceb8c2011-06-02 10:05:39 -070036 : DBus::ObjectAdaptor(*conn, object_path) {
Darin Petkov67d8ecf2011-07-26 16:03:30 -070037 VLOG(2) << "DBusAdaptor: " << object_path;
Chris Masoned0ceb8c2011-06-02 10:05:39 -070038}
39
40DBusAdaptor::~DBusAdaptor() {}
41
42// static
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -080043bool DBusAdaptor::SetProperty(PropertyStore *store,
44 const string &name,
45 const ::DBus::Variant &value,
46 ::DBus::Error *error) {
mukesh agrawalffa3d042011-10-06 15:26:10 -070047 Error e;
Chris Masone8fe2c7e2011-06-09 15:51:19 -070048
49 if (DBusAdaptor::IsBool(value.signature()))
mukesh agrawalffa3d042011-10-06 15:26:10 -070050 store->SetBoolProperty(name, value.reader().get_bool(), &e);
Chris Masone8fe2c7e2011-06-09 15:51:19 -070051 else if (DBusAdaptor::IsByte(value.signature()))
mukesh agrawalffa3d042011-10-06 15:26:10 -070052 store->SetUint8Property(name, value.reader().get_byte(), &e);
Chris Masone8fe2c7e2011-06-09 15:51:19 -070053 else if (DBusAdaptor::IsInt16(value.signature()))
mukesh agrawalffa3d042011-10-06 15:26:10 -070054 store->SetInt16Property(name, value.reader().get_int16(), &e);
Chris Masone8fe2c7e2011-06-09 15:51:19 -070055 else if (DBusAdaptor::IsInt32(value.signature()))
mukesh agrawalffa3d042011-10-06 15:26:10 -070056 store->SetInt32Property(name, value.reader().get_int32(), &e);
Chris Masone3bd3c8c2011-06-13 08:20:26 -070057 else if (DBusAdaptor::IsPath(value.signature()))
mukesh agrawalffa3d042011-10-06 15:26:10 -070058 store->SetStringProperty(name, value.reader().get_path(), &e);
Chris Masone8fe2c7e2011-06-09 15:51:19 -070059 else if (DBusAdaptor::IsString(value.signature()))
mukesh agrawalffa3d042011-10-06 15:26:10 -070060 store->SetStringProperty(name, value.reader().get_string(), &e);
Chris Masone8fe2c7e2011-06-09 15:51:19 -070061 else if (DBusAdaptor::IsStringmap(value.signature()))
mukesh agrawalffa3d042011-10-06 15:26:10 -070062 store->SetStringmapProperty(name,
63 value.operator map<string, string>(),
64 &e);
65 else if (DBusAdaptor::IsStringmaps(value.signature())) {
Chris Masone27c4aa52011-07-02 13:10:14 -070066 VLOG(1) << " can't yet handle setting type " << value.signature();
mukesh agrawalffa3d042011-10-06 15:26:10 -070067 e.Populate(Error::kInternalError);
68 } else if (DBusAdaptor::IsStrings(value.signature()))
69 store->SetStringsProperty(name, value.operator vector<string>(), &e);
Chris Masone8fe2c7e2011-06-09 15:51:19 -070070 else if (DBusAdaptor::IsUint16(value.signature()))
mukesh agrawalffa3d042011-10-06 15:26:10 -070071 store->SetUint16Property(name, value.reader().get_uint16(), &e);
Chris Masone8fe2c7e2011-06-09 15:51:19 -070072 else if (DBusAdaptor::IsUint32(value.signature()))
mukesh agrawalffa3d042011-10-06 15:26:10 -070073 store->SetUint32Property(name, value.reader().get_uint32(), &e);
Eric Shienbroodb23d4b92012-02-16 12:32:42 -050074 else if (DBusAdaptor::IsKeyValueStore(value.signature())) {
75 VLOG(1) << " can't yet handle setting type " << value.signature();
76 e.Populate(Error::kInternalError);
77 } else {
Chris Masone27c4aa52011-07-02 13:10:14 -070078 NOTREACHED() << " unknown type: " << value.signature();
mukesh agrawalffa3d042011-10-06 15:26:10 -070079 e.Populate(Error::kInternalError);
Chris Masone27c4aa52011-07-02 13:10:14 -070080 }
mukesh agrawalffa3d042011-10-06 15:26:10 -070081
82 if (error != NULL) {
83 e.ToDBusError(error);
84 }
85
86 return e.IsSuccess();
Chris Masone8fe2c7e2011-06-09 15:51:19 -070087}
88
89// static
mukesh agrawalde29fa82011-09-16 16:16:36 -070090bool DBusAdaptor::GetProperties(const PropertyStore &store,
Chris Masonea8a2c252011-06-27 22:16:30 -070091 map<string, ::DBus::Variant> *out,
mukesh agrawal1830fa12011-09-26 14:31:40 -070092 ::DBus::Error */*error*/) {
Gaurav Shah1b7a6162011-11-09 11:41:01 -080093 Error e;
Chris Masonea8a2c252011-06-27 22:16:30 -070094 {
Gaurav Shah1b7a6162011-11-09 11:41:01 -080095 ReadablePropertyConstIterator<bool> it = store.GetBoolPropertiesIter();
Chris Masonea8a2c252011-06-27 22:16:30 -070096 for ( ; !it.AtEnd(); it.Advance())
Gaurav Shah1b7a6162011-11-09 11:41:01 -080097 (*out)[it.Key()] = BoolToVariant(it.Value(&e));
Chris Masonea8a2c252011-06-27 22:16:30 -070098 }
99 {
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800100 ReadablePropertyConstIterator<int16> it = store.GetInt16PropertiesIter();
Chris Masonea8a2c252011-06-27 22:16:30 -0700101 for ( ; !it.AtEnd(); it.Advance())
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800102 (*out)[it.Key()] = Int16ToVariant(it.Value(&e));
Chris Masonea8a2c252011-06-27 22:16:30 -0700103 }
104 {
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800105 ReadablePropertyConstIterator<int32> it = store.GetInt32PropertiesIter();
Chris Masonea8a2c252011-06-27 22:16:30 -0700106 for ( ; !it.AtEnd(); it.Advance())
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800107 (*out)[it.Key()] = Int32ToVariant(it.Value(&e));
Chris Masonea8a2c252011-06-27 22:16:30 -0700108 }
109 {
Darin Petkov63138a92012-02-06 14:09:15 +0100110 ReadablePropertyConstIterator<KeyValueStore> it =
111 store.GetKeyValueStorePropertiesIter();
112 for ( ; !it.AtEnd(); it.Advance())
113 (*out)[it.Key()] = KeyValueStoreToVariant(it.Value(&e));
114 }
115 {
mukesh agrawal2366eed2012-03-20 18:21:50 -0700116 ReadablePropertyConstIterator<RpcIdentifiers> it =
117 store.GetRpcIdentifiersPropertiesIter();
118 for ( ; !it.AtEnd(); it.Advance()) {
119 Strings rpc_identifiers_as_strings = it.Value(&e);
120 vector < ::DBus::Path> rpc_identifiers_as_paths;
121 for (Strings::const_iterator in = rpc_identifiers_as_strings.begin();
122 in != rpc_identifiers_as_strings.end();
123 ++in) {
124 rpc_identifiers_as_paths.push_back(*in);
125 }
126 (*out)[it.Key()] = PathsToVariant(rpc_identifiers_as_paths);
127 }
128 }
129 {
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800130 ReadablePropertyConstIterator<string> it = store.GetStringPropertiesIter();
Chris Masonea8a2c252011-06-27 22:16:30 -0700131 for ( ; !it.AtEnd(); it.Advance())
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800132 (*out)[it.Key()] = StringToVariant(it.Value(&e));
Chris Masonea8a2c252011-06-27 22:16:30 -0700133 }
134 {
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800135 ReadablePropertyConstIterator<Stringmap> it =
136 store.GetStringmapPropertiesIter();
Chris Masonea8a2c252011-06-27 22:16:30 -0700137 for ( ; !it.AtEnd(); it.Advance())
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800138 (*out)[it.Key()]= StringmapToVariant(it.Value(&e));
Chris Masonea8a2c252011-06-27 22:16:30 -0700139 }
140 {
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800141 ReadablePropertyConstIterator<Strings> it =
142 store.GetStringsPropertiesIter();
Chris Masonea8a2c252011-06-27 22:16:30 -0700143 for ( ; !it.AtEnd(); it.Advance())
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800144 (*out)[it.Key()] = StringsToVariant(it.Value(&e));
Chris Masonea8a2c252011-06-27 22:16:30 -0700145 }
146 {
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800147 ReadablePropertyConstIterator<uint8> it = store.GetUint8PropertiesIter();
Chris Masonea8a2c252011-06-27 22:16:30 -0700148 for ( ; !it.AtEnd(); it.Advance())
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800149 (*out)[it.Key()] = ByteToVariant(it.Value(&e));
Chris Masonea8a2c252011-06-27 22:16:30 -0700150 }
151 {
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800152 ReadablePropertyConstIterator<uint16> it = store.GetUint16PropertiesIter();
Chris Masonea8a2c252011-06-27 22:16:30 -0700153 for ( ; !it.AtEnd(); it.Advance())
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800154 (*out)[it.Key()] = Uint16ToVariant(it.Value(&e));
Chris Masonea8a2c252011-06-27 22:16:30 -0700155 }
156 {
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800157 ReadablePropertyConstIterator<uint32> it = store.GetUint32PropertiesIter();
Chris Masonea8a2c252011-06-27 22:16:30 -0700158 for ( ; !it.AtEnd(); it.Advance())
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800159 (*out)[it.Key()] = Uint32ToVariant(it.Value(&e));
Chris Masonea8a2c252011-06-27 22:16:30 -0700160 }
161 return true;
162}
163
164// static
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800165bool DBusAdaptor::ClearProperty(PropertyStore *store,
166 const string &name,
167 ::DBus::Error *error) {
168 Error e;
169 store->ClearProperty(name, &e);
170
171 if (error != NULL) {
172 e.ToDBusError(error);
173 }
174
175 return e.IsSuccess();
176}
177
178// static
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700179void DBusAdaptor::ArgsToKeyValueStore(
180 const map<string, ::DBus::Variant> &args,
181 KeyValueStore *out,
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800182 Error *error) { // TODO(quiche): Should be ::DBus::Error?
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700183 for (map<string, ::DBus::Variant>::const_iterator it = args.begin();
184 it != args.end();
185 ++it) {
186 DBus::type<string> string_type;
187 DBus::type<bool> bool_type;
188
189 if (it->second.signature() == string_type.sig()) {
190 out->SetString(it->first, it->second.reader().get_string());
191 } else if (it->second.signature() == bool_type.sig()) {
192 out->SetBool(it->first, it->second.reader().get_bool());
193 } else {
194 error->Populate(Error::kInternalError);
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800195 return; // Skip remaining args after error.
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700196 }
197 }
198}
199
200// static
Chris Masoned0ceb8c2011-06-02 10:05:39 -0700201::DBus::Variant DBusAdaptor::BoolToVariant(bool value) {
202 ::DBus::Variant v;
203 v.writer().append_bool(value);
204 return v;
205}
206
207// static
Paul Stewartced6a0b2011-11-08 15:32:04 -0800208::DBus::Variant DBusAdaptor::ByteArraysToVariant(const ByteArrays &value) {
209 ::DBus::MessageIter writer;
210 ::DBus::Variant v;
211
Gaurav Shah7ad8e532011-11-11 17:14:49 -0800212
213 // We have to use a local because the operator<< needs a reference
214 // to work on (the lhs) but writer() returns by-value. C++ prohibits
215 // initializing non-const references from a temporary.
216 // So:
217 // v.writer() << value;
218 // would NOT automagically promote the returned value of v.writer() to
219 // a non-const reference (if you think about it, that's almost always not what
220 // you'd want. see: http://gcc.gnu.org/ml/gcc-help/2006-04/msg00075.html).
221 //
222 // One could consider changing writer() to return a reference, but then it
223 // changes writer() semantics as it can not be a const reference. writer()
224 // currently doesn't modify the original object on which it's called.
Paul Stewartced6a0b2011-11-08 15:32:04 -0800225 writer = v.writer();
226 writer << value;
227 return v;
228}
229
230// static
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700231::DBus::Variant DBusAdaptor::ByteToVariant(uint8 value) {
Chris Masoned0ceb8c2011-06-02 10:05:39 -0700232 ::DBus::Variant v;
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700233 v.writer().append_byte(value);
Chris Masoned0ceb8c2011-06-02 10:05:39 -0700234 return v;
235}
236
237// static
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700238::DBus::Variant DBusAdaptor::Int16ToVariant(int16 value) {
239 ::DBus::Variant v;
240 v.writer().append_int16(value);
241 return v;
242}
243
244// static
245::DBus::Variant DBusAdaptor::Int32ToVariant(int32 value) {
Chris Masoned0ceb8c2011-06-02 10:05:39 -0700246 ::DBus::Variant v;
247 v.writer().append_int32(value);
248 return v;
249}
250
251// static
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700252::DBus::Variant DBusAdaptor::PathToVariant(const ::DBus::Path &value) {
253 ::DBus::Variant v;
254 v.writer().append_path(value.c_str());
255 return v;
256}
257
258// static
mukesh agrawal2366eed2012-03-20 18:21:50 -0700259::DBus::Variant DBusAdaptor::PathsToVariant(
mukesh agrawal32399322011-09-01 10:53:43 -0700260 const vector< ::DBus::Path> &value) {
261 ::DBus::MessageIter writer;
262 ::DBus::Variant v;
263
Gaurav Shah7ad8e532011-11-11 17:14:49 -0800264 // See note above on why we need to use a local.
mukesh agrawal32399322011-09-01 10:53:43 -0700265 writer = v.writer();
266 writer << value;
267 return v;
268}
269
270// static
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700271::DBus::Variant DBusAdaptor::StringToVariant(const string &value) {
Chris Masoned0ceb8c2011-06-02 10:05:39 -0700272 ::DBus::Variant v;
273 v.writer().append_string(value.c_str());
274 return v;
275}
276
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700277// static
Chris Masone889666b2011-07-03 12:58:50 -0700278::DBus::Variant DBusAdaptor::StringmapToVariant(const Stringmap &value) {
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700279 ::DBus::Variant v;
280 ::DBus::MessageIter writer = v.writer();
281 writer << value;
282 return v;
283}
284
285// static
Chris Masone889666b2011-07-03 12:58:50 -0700286::DBus::Variant DBusAdaptor::StringmapsToVariant(const Stringmaps &value) {
Chris Masoneb925cc82011-06-22 15:39:57 -0700287 ::DBus::Variant v;
288 ::DBus::MessageIter writer = v.writer();
289 writer << value;
290 return v;
291}
292
293// static
Chris Masone889666b2011-07-03 12:58:50 -0700294::DBus::Variant DBusAdaptor::StringsToVariant(const Strings &value) {
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700295 ::DBus::Variant v;
296 ::DBus::MessageIter writer = v.writer();
297 writer << value;
298 return v;
299}
300
301// static
Darin Petkov63138a92012-02-06 14:09:15 +0100302::DBus::Variant DBusAdaptor::KeyValueStoreToVariant(
303 const KeyValueStore &value) {
Chris Masone889666b2011-07-03 12:58:50 -0700304 ::DBus::Variant v;
305 ::DBus::MessageIter writer = v.writer();
Eric Shienbroodb23d4b92012-02-16 12:32:42 -0500306 map<string, ::DBus::Variant> props;
307 {
308 map<string, string>::const_iterator it;
309 for (it = value.string_properties().begin();
310 it != value.string_properties().end();
311 ++it) {
312 ::DBus::Variant vv;
313 ::DBus::MessageIter writer = vv.writer();
314 writer.append_string(it->second.c_str());
315 props[it->first] = vv;
316 }
317 }
318 {
319 map<string, bool>::const_iterator it;
320 for (it = value.bool_properties().begin();
321 it != value.bool_properties().end();
322 ++it) {
323 ::DBus::Variant vv;
324 ::DBus::MessageIter writer = vv.writer();
325 writer.append_bool(it->second);
326 props[it->first] = vv;
327 }
328 }
329 {
330 map<string, uint32>::const_iterator it;
331 for (it = value.uint_properties().begin();
332 it != value.uint_properties().end();
333 ++it) {
334 ::DBus::Variant vv;
335 ::DBus::MessageIter writer = vv.writer();
336 writer.append_uint32(it->second);
337 props[it->first] = vv;
338 }
339 }
340 writer << props;
Chris Masone889666b2011-07-03 12:58:50 -0700341 return v;
342}
343
344// static
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700345::DBus::Variant DBusAdaptor::Uint16ToVariant(uint16 value) {
346 ::DBus::Variant v;
347 v.writer().append_uint16(value);
348 return v;
349}
350
351// static
352::DBus::Variant DBusAdaptor::Uint32ToVariant(uint32 value) {
353 ::DBus::Variant v;
354 v.writer().append_uint32(value);
355 return v;
356}
357
358// static
359bool DBusAdaptor::IsBool(::DBus::Signature signature) {
360 return signature == ::DBus::type<bool>::sig();
361}
362
363// static
364bool DBusAdaptor::IsByte(::DBus::Signature signature) {
365 return signature == ::DBus::type<uint8>::sig();
366}
367
368// static
Paul Stewartced6a0b2011-11-08 15:32:04 -0800369bool DBusAdaptor::IsByteArrays(::DBus::Signature signature) {
370 return signature == DBusAdaptor::kByteArraysSig;
371}
372
373// static
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700374bool DBusAdaptor::IsInt16(::DBus::Signature signature) {
375 return signature == ::DBus::type<int16>::sig();
376}
377
378// static
379bool DBusAdaptor::IsInt32(::DBus::Signature signature) {
380 return signature == ::DBus::type<int32>::sig();
381}
382
383// static
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700384bool DBusAdaptor::IsPath(::DBus::Signature signature) {
385 return signature == ::DBus::type< ::DBus::Path >::sig();
386}
387
388// static
mukesh agrawal2366eed2012-03-20 18:21:50 -0700389bool DBusAdaptor::IsPaths(::DBus::Signature signature) {
390 return signature == DBusAdaptor::kPathsSig;
mukesh agrawal32399322011-09-01 10:53:43 -0700391}
392
393// static
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700394bool DBusAdaptor::IsString(::DBus::Signature signature) {
395 return signature == ::DBus::type<string>::sig();
396}
397
398// static
399bool DBusAdaptor::IsStringmap(::DBus::Signature signature) {
400 return signature == DBusAdaptor::kStringmapSig;
401}
402
403// static
Chris Masone27c4aa52011-07-02 13:10:14 -0700404bool DBusAdaptor::IsStringmaps(::DBus::Signature signature) {
405 return signature == DBusAdaptor::kStringmapsSig;
406}
407
408// static
Chris Masone8fe2c7e2011-06-09 15:51:19 -0700409bool DBusAdaptor::IsStrings(::DBus::Signature signature) {
410 return signature == DBusAdaptor::kStringsSig;
411}
412
413// static
414bool DBusAdaptor::IsUint16(::DBus::Signature signature) {
415 return signature == ::DBus::type<uint16>::sig();
416}
417
418// static
419bool DBusAdaptor::IsUint32(::DBus::Signature signature) {
420 return signature == ::DBus::type<uint32>::sig();
421}
422
Darin Petkove5bc2cb2011-12-07 14:47:32 +0100423// static
Eric Shienbroodb23d4b92012-02-16 12:32:42 -0500424bool DBusAdaptor::IsKeyValueStore(::DBus::Signature signature) {
425 return signature == ::DBus::type<map<string, ::DBus::Variant> >::sig();
426}
427
428// static
Darin Petkove5bc2cb2011-12-07 14:47:32 +0100429DBusAdaptor::Returner *DBusAdaptor::Returner::Create(DBusAdaptor *adaptor) {
430 return new Returner(adaptor);
431}
432
433DBusAdaptor::Returner::Returner(DBusAdaptor *adaptor)
434 : adaptor_(adaptor),
435 state_(kStateInitialized) {
436 VLOG(2) << __func__ << " @ " << this;
437}
438
439DBusAdaptor::Returner::~Returner() {
440 CHECK(state_ != kStateDestroyed);
441 VLOG(2) << "Destroying returner @ " << this << " state: " << state_;
442 adaptor_ = NULL;
443 state_ = kStateDestroyed;
444}
445
446void DBusAdaptor::Returner::Return() {
447 VLOG(2) << __func__ << " @ " << this << " state: " << state_;
448 switch (state_) {
449 case kStateInitialized:
450 // Service method is returning right away, without any continuation.
451 state_ = kStateReturned;
452 return;
453 case kStateDelayed: {
454 // This return happens in the continuation.
455 DBus::ObjectAdaptor::Continuation *cont =
456 adaptor_->find_continuation(this);
457 CHECK(cont);
458 adaptor_->return_now(cont);
459 delete this;
460 return;
461 }
462 default:
463 NOTREACHED() << "Unexpected state: " << state_;
464 break;
465 }
466}
467
468void DBusAdaptor::Returner::ReturnError(const Error &error) {
469 VLOG(2) << __func__ << " @ " << this << " state: " << state_;
470 switch (state_) {
471 case kStateInitialized:
472 // Service method is returning right away, without any continuation.
473 error_.CopyFrom(error);
474 state_ = kStateReturned;
475 return;
476 case kStateDelayed: {
477 // This return happens in the continuation.
478 DBus::Error dbus_error;
479 error.ToDBusError(&dbus_error);
480 DBus::ObjectAdaptor::Continuation *cont =
481 adaptor_->find_continuation(this);
482 CHECK(cont);
483 adaptor_->return_error(cont, dbus_error);
484 delete this;
485 return;
486 }
487 default:
488 NOTREACHED() << "Unexpected state: " << state_;
489 break;
490 }
491}
492
493void DBusAdaptor::Returner::DelayOrReturn(DBus::Error *error) {
494 VLOG(2) << __func__ << " @ " << this << " state: " << state_;
495 switch (state_) {
496 case kStateInitialized:
497 // Service method needs continuation so delay the return.
498 state_ = kStateDelayed;
499
500 // return_later does not return. It unwinds the stack up to the dbus-c++
501 // message handler by throwing an exception.
502 adaptor_->return_later(this);
503 return;
504 case kStateReturned:
505 // Service method has returned right away, without any continuation.
506 error_.ToDBusError(error);
507 delete this;
508 return;
509 default:
510 NOTREACHED() << "Unexpected state: " << state_;
511 break;
512 }
513}
514
Chris Masoned0ceb8c2011-06-02 10:05:39 -0700515} // namespace shill