[shill] Add support for setting properties.
This CL adds a framework for supporting RPC-exposed properties in Shill.
It also plumbs the code for setting properties on Service objects to prove
the approach. Device and Manager settings will follow.
BUG=chromium-os:16343
TEST=build shill, run unit tests.
Change-Id: I55869453d6039e688f1a49be9dfb1ba1315efe0a
Reviewed-on: http://gerrit.chromium.org/gerrit/3004
Reviewed-by: Darin Petkov <petkov@chromium.org>
Tested-by: Chris Masone <cmasone@chromium.org>
diff --git a/Makefile b/Makefile
index 65742c4..2348b2a 100644
--- a/Makefile
+++ b/Makefile
@@ -42,6 +42,8 @@
DBUS_HEADERS = $(DBUS_ADAPTOR_HEADERS) $(DBUS_PROXY_HEADERS)
SHILL_OBJS = \
+ cellular.o \
+ cellular_service.o \
dbus_adaptor.o \
dbus_control.o \
device.o \
@@ -86,6 +88,7 @@
mock_control.o \
mock_device.o \
mock_service.o \
+ service_unittest.o \
shill_unittest.o \
testrunner.o
diff --git a/accessor_interface.h b/accessor_interface.h
new file mode 100644
index 0000000..85f3913
--- /dev/null
+++ b/accessor_interface.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2011 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.
+
+#ifndef SHILL_ACCESSOR_INTERFACE_
+#define SHILL_ACCESSOR_INTERFACE_
+
+#include <map>
+#include <string>
+#include <tr1/memory>
+
+#include <base/basictypes.h>
+
+namespace shill {
+
+// A templated abstract base class for objects that can be used to access
+// properties stored in objects that are meant to be made available over RPC.
+// The intended usage is that an object stores a maps of strings to
+// AccessorInterfaces of the appropriate type, and then uses
+// map[name]->Get() and map[name]->Set(value) to get and set the properties.
+template <class T>
+class AccessorInterface {
+ public:
+ AccessorInterface() {}
+ virtual ~AccessorInterface() {}
+
+ // Provides read-only access.
+ virtual const T &Get() = 0;
+ // Attempts to set the wrapped value. Returns true upon success.
+ virtual bool Set(const T &value) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AccessorInterface);
+};
+
+// Using a smart pointer here allows pointers to classes derived from
+// AccessorInterface<> to be stored in maps and other STL container types.
+typedef std::tr1::shared_ptr<AccessorInterface<bool> > BoolAccessor;
+typedef std::tr1::shared_ptr<AccessorInterface<int32> > Int32Accessor;
+typedef std::tr1::shared_ptr<
+ AccessorInterface<std::map<std::string, std::string> > > StringmapAccessor;
+typedef std::tr1::shared_ptr<AccessorInterface<std::string> > StringAccessor;
+typedef std::tr1::shared_ptr<AccessorInterface<uint8> > Uint8Accessor;
+typedef std::tr1::shared_ptr<AccessorInterface<uint16> > Uint16Accessor;
+
+} // namespace shill
+
+#endif // SHILL_ACCESSOR_INTERFACE_
diff --git a/cellular.cc b/cellular.cc
new file mode 100644
index 0000000..92e8262
--- /dev/null
+++ b/cellular.cc
@@ -0,0 +1,57 @@
+// Copyright (c) 2011 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 "shill/cellular.h"
+
+#include <string>
+
+#include <base/logging.h>
+
+#include "shill/cellular_service.h"
+#include "shill/control_interface.h"
+#include "shill/device.h"
+#include "shill/device_info.h"
+#include "shill/manager.h"
+#include "shill/shill_event.h"
+
+using std::string;
+
+namespace shill {
+
+Cellular::Cellular(ControlInterface *control_interface,
+ EventDispatcher *dispatcher,
+ Manager *manager,
+ const string &link,
+ int interface_index)
+ : Device(control_interface,
+ dispatcher,
+ manager,
+ link,
+ interface_index),
+ service_(new CellularService(control_interface,
+ dispatcher,
+ this,
+ "service-" + link)),
+ service_registered_(false) {
+ VLOG(2) << "Cellular device " << link_name() << " initialized.";
+}
+
+Cellular::~Cellular() {
+ Stop();
+}
+
+void Cellular::Start() {
+ Device::Start();
+}
+
+void Cellular::Stop() {
+ manager_->DeregisterService(service_.get());
+ Device::Stop();
+}
+
+bool Cellular::TechnologyIs(const Device::Technology type) {
+ return type == Device::kCellular;
+}
+
+} // namespace shill
diff --git a/cellular.h b/cellular.h
new file mode 100644
index 0000000..428aa21
--- /dev/null
+++ b/cellular.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2011 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.
+
+#ifndef SHILL_CELLULAR_
+#define SHILL_CELLULAR_
+
+#include <string>
+
+#include <base/basictypes.h>
+
+#include "shill/cellular_service.h"
+#include "shill/device.h"
+#include "shill/shill_event.h"
+
+namespace shill {
+
+class Cellular : public Device {
+ public:
+ Cellular(ControlInterface *control_interface,
+ EventDispatcher *dispatcher,
+ Manager *manager,
+ const std::string& link,
+ int interface_index);
+ ~Cellular();
+ void Start();
+ void Stop();
+ bool TechnologyIs(Device::Technology type);
+
+ private:
+ bool service_registered_;
+ ServiceRefPtr service_;
+ DISALLOW_COPY_AND_ASSIGN(Cellular);
+};
+
+} // namespace shill
+
+#endif // SHILL_CELLULAR_
diff --git a/cellular_service.cc b/cellular_service.cc
new file mode 100644
index 0000000..a125c77
--- /dev/null
+++ b/cellular_service.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2011 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 "shill/cellular_service.h"
+
+#include <string>
+
+#include <base/logging.h>
+#include <chromeos/dbus/service_constants.h>
+
+#include "shill/cellular.h"
+#include "shill/control_interface.h"
+#include "shill/device.h"
+#include "shill/device_info.h"
+#include "shill/manager.h"
+#include "shill/shill_event.h"
+
+using std::string;
+
+namespace shill {
+CellularService::CellularService(ControlInterface *control_interface,
+ EventDispatcher *dispatcher,
+ Cellular *device,
+ const string &name)
+ : Service(control_interface, dispatcher, device, name),
+ cellular_(device),
+ strength_(0),
+ type_(flimflam::kTypeCellular) {
+
+ RegisterConstString(flimflam::kActivationStateProperty, &activation_state_);
+ RegisterConstString(flimflam::kOperatorNameProperty, &operator_name_);
+ RegisterConstString(flimflam::kOperatorCodeProperty, &operator_code_);
+ RegisterConstString(flimflam::kNetworkTechnologyProperty, &network_tech_);
+ RegisterConstString(flimflam::kRoamingStateProperty, &roaming_state_);
+ RegisterConstString(flimflam::kPaymentURLProperty, &payment_url_);
+
+ RegisterStringmap(flimflam::kCellularApnProperty, &apn_info_);
+ RegisterConstStringmap(flimflam::kCellularLastGoodApnProperty,
+ &last_good_apn_info_);
+
+ RegisterConstUint8(flimflam::kSignalStrengthProperty, &strength_);
+ // RegisterDerivedString(flimflam::kStateProperty,
+ // &Service::CalculateState,
+ // NULL);
+ RegisterConstString(flimflam::kTypeProperty, &type_);
+}
+
+CellularService::~CellularService() { }
+
+void CellularService::Connect() { }
+
+void CellularService::Disconnect() { }
+
+bool CellularService::Contains(const string &property) {
+ return (Service::Contains(property) ||
+ uint8_properties_.find(property) != uint8_properties_.end() ||
+ stringmap_properties_.find(property) != stringmap_properties_.end());
+}
+
+} // namespace shill
diff --git a/cellular_service.h b/cellular_service.h
new file mode 100644
index 0000000..710c0b5
--- /dev/null
+++ b/cellular_service.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2011 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.
+
+#ifndef SHILL_CELLULAR_SERVICE_
+#define SHILL_CELLULAR_SERVICE_
+
+#include <map>
+#include <string>
+
+#include <base/basictypes.h>
+
+#include "shill/cellular.h"
+#include "shill/device.h"
+#include "shill/shill_event.h"
+#include "shill/service.h"
+
+namespace shill {
+
+class Cellular;
+
+class CellularService : public Service {
+ public:
+ CellularService(ControlInterface *control_interface,
+ EventDispatcher *dispatcher,
+ Cellular *device,
+ const std::string& name);
+ ~CellularService();
+ void Connect();
+ void Disconnect();
+
+ // Implementation of PropertyStoreInterface
+ bool Contains(const std::string &property);
+
+ protected:
+ virtual std::string CalculateState() { return "idle"; }
+
+ // Properties
+ std::string activation_state_;
+ std::string operator_name_;
+ std::string operator_code_;
+ std::string network_tech_;
+ std::string roaming_state_;
+ std::string payment_url_;
+ uint8 strength_;
+
+ std::map<std::string, std::string> apn_info_;
+ std::map<std::string, std::string> last_good_apn_info_;
+
+ private:
+ Cellular *cellular_;
+ const std::string type_;
+ DISALLOW_COPY_AND_ASSIGN(CellularService);
+};
+
+} // namespace shill
+
+#endif // SHILL_CELLULAR_SERVICE_
diff --git a/dbus_adaptor.cc b/dbus_adaptor.cc
index 9b57ba2..748832c 100644
--- a/dbus_adaptor.cc
+++ b/dbus_adaptor.cc
@@ -35,6 +35,10 @@
const string &name,
const ::DBus::Variant &value,
::DBus::Error &error) {
+ if (!store->Contains(name)) {
+ Error(Error::kInvalidProperty, name + " is invalid.").ToDBusError(&error);
+ return false;
+ }
bool set = false;
Error e(Error::kInvalidArguments, "Could not write " + name);
@@ -46,6 +50,8 @@
set = store->SetInt16Property(name, value.reader().get_int16(), &e);
else if (DBusAdaptor::IsInt32(value.signature()))
set = store->SetInt32Property(name, value.reader().get_int32(), &e);
+ else if (DBusAdaptor::IsPath(value.signature()))
+ set = store->SetStringProperty(name, value.reader().get_path(), &e);
else if (DBusAdaptor::IsString(value.signature()))
set = store->SetStringProperty(name, value.reader().get_string(), &e);
else if (DBusAdaptor::IsStringmap(value.signature()))
@@ -95,6 +101,13 @@
}
// static
+::DBus::Variant DBusAdaptor::PathToVariant(const ::DBus::Path &value) {
+ ::DBus::Variant v;
+ v.writer().append_path(value.c_str());
+ return v;
+}
+
+// static
::DBus::Variant DBusAdaptor::StringToVariant(const string &value) {
::DBus::Variant v;
v.writer().append_string(value.c_str());
@@ -153,6 +166,11 @@
}
// static
+bool DBusAdaptor::IsPath(::DBus::Signature signature) {
+ return signature == ::DBus::type< ::DBus::Path >::sig();
+}
+
+// static
bool DBusAdaptor::IsString(::DBus::Signature signature) {
return signature == ::DBus::type<string>::sig();
}
diff --git a/dbus_adaptor.h b/dbus_adaptor.h
index 18aa3f3..13ede16 100644
--- a/dbus_adaptor.h
+++ b/dbus_adaptor.h
@@ -34,6 +34,7 @@
static ::DBus::Variant ByteToVariant(uint8 value);
static ::DBus::Variant Int16ToVariant(int16 value);
static ::DBus::Variant Int32ToVariant(int32 value);
+ static ::DBus::Variant PathToVariant(const ::DBus::Path& value);
static ::DBus::Variant StringToVariant(const std::string& value);
static ::DBus::Variant StringmapToVariant(
const std::map<std::string, std::string>& value);
@@ -46,6 +47,7 @@
static bool IsByte(::DBus::Signature signature);
static bool IsInt16(::DBus::Signature signature);
static bool IsInt32(::DBus::Signature signature);
+ static bool IsPath(::DBus::Signature signature);
static bool IsString(::DBus::Signature signature);
static bool IsStringmap(::DBus::Signature signature);
static bool IsStrings(::DBus::Signature signature);
diff --git a/dbus_adaptor_unittest.cc b/dbus_adaptor_unittest.cc
index 3a49895..22fd803 100644
--- a/dbus_adaptor_unittest.cc
+++ b/dbus_adaptor_unittest.cc
@@ -15,20 +15,22 @@
#include "shill/manager.h"
#include "shill/mock_control.h"
#include "shill/mock_device.h"
+#include "shill/mock_property_store.h"
#include "shill/mock_service.h"
+#include "shill/property_store_unittest.h"
#include "shill/shill_event.h"
using std::map;
using std::string;
using std::vector;
-using ::testing::Test;
using ::testing::_;
-using ::testing::NiceMock;
using ::testing::Return;
+using ::testing::StrEq;
+using ::testing::Test;
namespace shill {
-class DBusAdaptorTest : public Test {
+class DBusAdaptorTest : public PropertyStoreTest {
public:
DBusAdaptorTest()
: ex_bool(true),
@@ -39,7 +41,6 @@
ex_int32(-65536),
ex_string("something"),
ex_strings(1, ex_string),
- manager_(&control_interface_, &dispatcher_),
device_(new MockDevice(&control_interface_,
&dispatcher_,
&manager_,
@@ -51,15 +52,15 @@
"mock")) {
ex_stringmap[ex_string] = ex_string;
- bool_v = DBusAdaptor::BoolToVariant(ex_bool);
- byte_v = DBusAdaptor::ByteToVariant(ex_byte);
- uint16_v = DBusAdaptor::Uint16ToVariant(ex_uint16);
- uint32_v = DBusAdaptor::Uint32ToVariant(ex_uint32);
- int16_v = DBusAdaptor::Int16ToVariant(ex_int16);
- int32_v = DBusAdaptor::Int32ToVariant(ex_int32);
- string_v = DBusAdaptor::StringToVariant(ex_string);
- stringmap_v = DBusAdaptor::StringmapToVariant(ex_stringmap);
- strings_v = DBusAdaptor::StringsToVariant(ex_strings);
+ bool_v_ = DBusAdaptor::BoolToVariant(ex_bool);
+ byte_v_ = DBusAdaptor::ByteToVariant(ex_byte);
+ uint16_v_ = DBusAdaptor::Uint16ToVariant(ex_uint16);
+ uint32_v_ = DBusAdaptor::Uint32ToVariant(ex_uint32);
+ int16_v_ = DBusAdaptor::Int16ToVariant(ex_int16);
+ int32_v_ = DBusAdaptor::Int32ToVariant(ex_int32);
+ string_v_ = DBusAdaptor::StringToVariant(ex_string);
+ stringmap_v_ = DBusAdaptor::StringmapToVariant(ex_stringmap);
+ strings_v_ = DBusAdaptor::StringsToVariant(ex_strings);
}
virtual ~DBusAdaptorTest() {}
@@ -74,118 +75,88 @@
map<string, string> ex_stringmap;
vector<string> ex_strings;
- ::DBus::Variant bool_v;
- ::DBus::Variant byte_v;
- ::DBus::Variant uint16_v;
- ::DBus::Variant uint32_v;
- ::DBus::Variant int16_v;
- ::DBus::Variant int32_v;
- ::DBus::Variant string_v;
- ::DBus::Variant stringmap_v;
- ::DBus::Variant strings_v;
-
protected:
- MockControl control_interface_;
- EventDispatcher dispatcher_;
- Manager manager_;
DeviceRefPtr device_;
ServiceRefPtr service_;
};
TEST_F(DBusAdaptorTest, Conversions) {
EXPECT_EQ(0, DBusAdaptor::BoolToVariant(0).reader().get_bool());
- EXPECT_EQ(ex_bool, bool_v.reader().get_bool());
+ EXPECT_EQ(ex_bool, bool_v_.reader().get_bool());
EXPECT_EQ(0, DBusAdaptor::ByteToVariant(0).reader().get_byte());
- EXPECT_EQ(ex_byte, byte_v.reader().get_byte());
+ EXPECT_EQ(ex_byte, byte_v_.reader().get_byte());
EXPECT_EQ(0, DBusAdaptor::Uint16ToVariant(0).reader().get_uint16());
- EXPECT_EQ(ex_uint16, uint16_v.reader().get_uint16());
+ EXPECT_EQ(ex_uint16, uint16_v_.reader().get_uint16());
EXPECT_EQ(0, DBusAdaptor::Int16ToVariant(0).reader().get_int16());
- EXPECT_EQ(ex_int16, int16_v.reader().get_int16());
+ EXPECT_EQ(ex_int16, int16_v_.reader().get_int16());
EXPECT_EQ(0, DBusAdaptor::Uint32ToVariant(0).reader().get_uint32());
- EXPECT_EQ(ex_uint32, uint32_v.reader().get_uint32());
+ EXPECT_EQ(ex_uint32, uint32_v_.reader().get_uint32());
EXPECT_EQ(0, DBusAdaptor::Int32ToVariant(0).reader().get_int32());
- EXPECT_EQ(ex_int32, int32_v.reader().get_int32());
+ EXPECT_EQ(ex_int32, int32_v_.reader().get_int32());
EXPECT_EQ(string(""), DBusAdaptor::StringToVariant("").reader().get_string());
- EXPECT_EQ(ex_string, string_v.reader().get_string());
+ EXPECT_EQ(ex_string, string_v_.reader().get_string());
EXPECT_EQ(ex_stringmap[ex_string],
- (stringmap_v.operator map<string, string>()[ex_string]));
- EXPECT_EQ(ex_strings[0], strings_v.operator vector<string>()[0]);
+ (stringmap_v_.operator map<string, string>()[ex_string]));
+ EXPECT_EQ(ex_strings[0], strings_v_.operator vector<string>()[0]);
}
TEST_F(DBusAdaptorTest, Signatures) {
- EXPECT_TRUE(DBusAdaptor::IsBool(bool_v.signature()));
- EXPECT_TRUE(DBusAdaptor::IsByte(byte_v.signature()));
- EXPECT_TRUE(DBusAdaptor::IsInt16(int16_v.signature()));
- EXPECT_TRUE(DBusAdaptor::IsInt32(int32_v.signature()));
- EXPECT_TRUE(DBusAdaptor::IsString(string_v.signature()));
- EXPECT_TRUE(DBusAdaptor::IsStringmap(stringmap_v.signature()));
- EXPECT_TRUE(DBusAdaptor::IsStrings(strings_v.signature()));
- EXPECT_TRUE(DBusAdaptor::IsUint16(uint16_v.signature()));
- EXPECT_TRUE(DBusAdaptor::IsUint32(uint32_v.signature()));
+ EXPECT_TRUE(DBusAdaptor::IsBool(bool_v_.signature()));
+ EXPECT_TRUE(DBusAdaptor::IsByte(byte_v_.signature()));
+ EXPECT_TRUE(DBusAdaptor::IsInt16(int16_v_.signature()));
+ EXPECT_TRUE(DBusAdaptor::IsInt32(int32_v_.signature()));
+ EXPECT_TRUE(DBusAdaptor::IsString(string_v_.signature()));
+ EXPECT_TRUE(DBusAdaptor::IsStringmap(stringmap_v_.signature()));
+ EXPECT_TRUE(DBusAdaptor::IsStrings(strings_v_.signature()));
+ EXPECT_TRUE(DBusAdaptor::IsUint16(uint16_v_.signature()));
+ EXPECT_TRUE(DBusAdaptor::IsUint32(uint32_v_.signature()));
- EXPECT_FALSE(DBusAdaptor::IsBool(byte_v.signature()));
- EXPECT_FALSE(DBusAdaptor::IsStrings(string_v.signature()));
+ EXPECT_FALSE(DBusAdaptor::IsBool(byte_v_.signature()));
+ EXPECT_FALSE(DBusAdaptor::IsStrings(string_v_.signature()));
}
TEST_F(DBusAdaptorTest, Dispatch) {
+ MockPropertyStore store;
::DBus::Error error;
- EXPECT_TRUE(DBusAdaptor::DispatchOnType(&manager_, "", bool_v, error));
- EXPECT_TRUE(DBusAdaptor::DispatchOnType(&manager_, "", string_v, error));
- EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_, "", strings_v, error));
- EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_, "", int16_v, error));
- EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_, "", int32_v, error));
- EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_, "", uint16_v, error));
- EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_, "", uint32_v, error));
- EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_, "", stringmap_v, error));
- EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_, "", byte_v, error));
+ EXPECT_CALL(store, Contains(_)).WillRepeatedly(Return(true));
+ EXPECT_CALL(store, SetBoolProperty("", _, _)).WillOnce(Return(true));
+ EXPECT_CALL(store, SetInt16Property("", _, _)).WillOnce(Return(true));
+ EXPECT_CALL(store, SetInt32Property("", _, _)).WillOnce(Return(true));
+ EXPECT_CALL(store, SetStringProperty("", _, _))
+ .WillOnce(Return(true));
+ EXPECT_CALL(store, SetStringmapProperty("", _, _))
+ .WillOnce(Return(true));
+ EXPECT_CALL(store, SetStringsProperty("", _, _))
+ .WillOnce(Return(true));
+ EXPECT_CALL(store, SetUint8Property("", _, _)).WillOnce(Return(true));
+ EXPECT_CALL(store, SetUint16Property("", _, _)).WillOnce(Return(true));
+ EXPECT_CALL(store, SetUint32Property("", _, _)).WillOnce(Return(true));
- EXPECT_TRUE(DBusAdaptor::DispatchOnType(device_.get(), "", bool_v, error));
- EXPECT_TRUE(DBusAdaptor::DispatchOnType(device_.get(), "", string_v, error));
- EXPECT_TRUE(DBusAdaptor::DispatchOnType(device_.get(), "", int16_v, error));
- EXPECT_TRUE(DBusAdaptor::DispatchOnType(device_.get(), "", int32_v, error));
- EXPECT_TRUE(DBusAdaptor::DispatchOnType(device_.get(), "", uint16_v, error));
- EXPECT_TRUE(DBusAdaptor::DispatchOnType(device_.get(), "", uint32_v, error));
+ string string_path("/false/path");
+ ::DBus::Path path(string_path);
+ ::DBus::Variant path_v = DBusAdaptor::PathToVariant(path);
+ EXPECT_CALL(store, SetStringProperty("", StrEq(string_path), _))
+ .WillOnce(Return(true));
- EXPECT_FALSE(DBusAdaptor::DispatchOnType(device_.get(), "", byte_v, error));
- EXPECT_FALSE(DBusAdaptor::DispatchOnType(device_.get(),
- "",
- strings_v,
- error));
- EXPECT_FALSE(DBusAdaptor::DispatchOnType(device_.get(),
- "",
- stringmap_v,
- error));
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(&store, "", bool_v_, error));
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(&store, "", path_v, error));
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(&store, "", string_v_, error));
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(&store, "", strings_v_, error));
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(&store, "", int16_v_, error));
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(&store, "", int32_v_, error));
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(&store, "", uint16_v_, error));
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(&store, "", uint32_v_, error));
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(&store, "", stringmap_v_, error));
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(&store, "", byte_v_, error));
- EXPECT_TRUE(DBusAdaptor::DispatchOnType(service_.get(), "", bool_v, error));
- EXPECT_TRUE(DBusAdaptor::DispatchOnType(service_.get(), "", byte_v, error));
- EXPECT_TRUE(DBusAdaptor::DispatchOnType(service_.get(), "", string_v, error));
- EXPECT_TRUE(DBusAdaptor::DispatchOnType(service_.get(), "", int32_v, error));
- EXPECT_TRUE(DBusAdaptor::DispatchOnType(service_.get(),
- "",
- stringmap_v,
- error));
-
- EXPECT_FALSE(DBusAdaptor::DispatchOnType(service_.get(), "", int16_v, error));
- EXPECT_FALSE(DBusAdaptor::DispatchOnType(service_.get(),
- "",
- uint16_v,
- error));
- EXPECT_FALSE(DBusAdaptor::DispatchOnType(service_.get(),
- "",
- uint32_v,
- error));
- EXPECT_FALSE(DBusAdaptor::DispatchOnType(service_.get(),
- "",
- strings_v,
- error));
}
} // namespace shill
diff --git a/device.cc b/device.cc
index e7103d3..9aab0f0 100644
--- a/device.cc
+++ b/device.cc
@@ -10,6 +10,7 @@
#include <base/logging.h>
#include <base/memory/ref_counted.h>
+#include <chromeos/dbus/service_constants.h>
#include "shill/control_interface.h"
#include "shill/device.h"
@@ -33,6 +34,33 @@
adaptor_(control_interface->CreateDeviceAdaptor(this)),
interface_index_(interface_index),
running_(false) {
+ known_properties_.push_back(flimflam::kNameProperty);
+ known_properties_.push_back(flimflam::kTypeProperty);
+ known_properties_.push_back(flimflam::kPoweredProperty);
+ known_properties_.push_back(flimflam::kScanningProperty);
+ // known_properties_.push_back(flimflam::kReconnectProperty);
+ known_properties_.push_back(flimflam::kScanIntervalProperty);
+ known_properties_.push_back(flimflam::kBgscanMethodProperty);
+ known_properties_.push_back(flimflam::kBgscanShortIntervalProperty);
+ known_properties_.push_back(flimflam::kBgscanSignalThresholdProperty);
+ known_properties_.push_back(flimflam::kNetworksProperty);
+ known_properties_.push_back(flimflam::kIPConfigsProperty);
+ known_properties_.push_back(flimflam::kCellularAllowRoamingProperty);
+ known_properties_.push_back(flimflam::kCarrierProperty);
+ known_properties_.push_back(flimflam::kMeidProperty);
+ known_properties_.push_back(flimflam::kImeiProperty);
+ known_properties_.push_back(flimflam::kImsiProperty);
+ known_properties_.push_back(flimflam::kEsnProperty);
+ known_properties_.push_back(flimflam::kMdnProperty);
+ known_properties_.push_back(flimflam::kModelIDProperty);
+ known_properties_.push_back(flimflam::kManufacturerProperty);
+ known_properties_.push_back(flimflam::kFirmwareRevisionProperty);
+ known_properties_.push_back(flimflam::kHardwareRevisionProperty);
+ known_properties_.push_back(flimflam::kPRLVersionProperty);
+ known_properties_.push_back(flimflam::kSIMLockStatusProperty);
+ known_properties_.push_back(flimflam::kFoundNetworksProperty);
+ known_properties_.push_back(flimflam::kDBusConnectionProperty);
+ known_properties_.push_back(flimflam::kDBusObjectProperty);
// Initialize Interface monitor, so we can detect new interfaces
VLOG(2) << "Device " << link_name_ << " index " << interface_index;
}
@@ -65,16 +93,17 @@
VLOG(2) << "Device " << link_name_ << " scan requested.";
}
-bool Device::SetBoolProperty(const string& name, bool value, Error *error) {
- VLOG(2) << "Setting " << name << " as a bool.";
- // TODO(cmasone): Set actual properties.
- return true;
+bool Device::Contains(const std::string &property) {
+ vector<string>::iterator it;
+ for (it = known_properties_.begin(); it != known_properties_.end(); ++it) {
+ if (property == *it)
+ return true;
+ }
+ return false;
}
-bool Device::SetInt16Property(const std::string& name,
- int16 value,
- Error *error) {
- VLOG(2) << "Setting " << name << " as an int16.";
+bool Device::SetBoolProperty(const string& name, bool value, Error *error) {
+ VLOG(2) << "Setting " << name << " as a bool.";
// TODO(cmasone): Set actual properties.
return true;
}
@@ -87,14 +116,6 @@
return true;
}
-bool Device::SetStringProperty(const string& name,
- const string& value,
- Error *error) {
- VLOG(2) << "Setting " << name << " as a string.";
- // TODO(cmasone): Set actual properties.
- return true;
-}
-
bool Device::SetUint16Property(const std::string& name,
uint16 value,
Error *error) {
@@ -103,14 +124,6 @@
return true;
}
-bool Device::SetUint32Property(const std::string& name,
- uint32 value,
- Error *error) {
- VLOG(2) << "Setting " << name << " as a uint32.";
- // TODO(cmasone): Set actual properties.
- return true;
-}
-
const string& Device::UniqueName() const {
// TODO(pstew): link_name is only run-time unique and won't persist
return link_name();
diff --git a/device.h b/device.h
index 4fd96d6..133b7a5 100644
--- a/device.h
+++ b/device.h
@@ -67,14 +67,16 @@
virtual void ConfigIP() {}
// Implementation of PropertyStoreInterface
- bool SetBoolProperty(const std::string& name, bool value, Error *error);
- bool SetInt16Property(const std::string& name, int16 value, Error *error);
- bool SetInt32Property(const std::string& name, int32 value, Error *error);
- bool SetStringProperty(const std::string& name,
- const std::string& value,
- Error *error);
- bool SetUint16Property(const std::string& name, uint16 value, Error *error);
- bool SetUint32Property(const std::string& name, uint32 value, Error *error);
+ virtual bool Contains(const std::string &property);
+ virtual bool SetBoolProperty(const std::string& name,
+ bool value,
+ Error *error);
+ virtual bool SetInt32Property(const std::string& name,
+ int32 value,
+ Error *error);
+ virtual bool SetUint16Property(const std::string& name,
+ uint16 value,
+ Error *error);
const std::string &link_name() const { return link_name_; }
@@ -102,6 +104,7 @@
bool running_;
Manager *manager_;
IPConfigRefPtr ipconfig_;
+ std::vector<std::string> known_properties_;
private:
friend class DeviceAdaptorInterface;
diff --git a/device_unittest.cc b/device_unittest.cc
index 0b81954..6d84221 100644
--- a/device_unittest.cc
+++ b/device_unittest.cc
@@ -2,16 +2,33 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <gtest/gtest.h>
-
#include "shill/device.h"
-#include "shill/dhcp_provider.h"
-#include "shill/mock_control.h"
-#include "shill/mock_glib.h"
-using testing::_;
-using testing::Return;
-using testing::Test;
+#include <map>
+#include <string>
+#include <vector>
+
+#include <dbus-c++/dbus.h>
+#include <chromeos/dbus/service_constants.h>
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+#include "shill/dbus_adaptor.h"
+#include "shill/dhcp_provider.h"
+#include "shill/manager.h"
+#include "shill/mock_control.h"
+#include "shill/mock_device.h"
+#include "shill/mock_glib.h"
+#include "shill/property_store_unittest.h"
+#include "shill/shill_event.h"
+
+using std::map;
+using std::string;
+using std::vector;
+using ::testing::_;
+using ::testing::NiceMock;
+using ::testing::Return;
+using ::testing::Test;
namespace shill {
@@ -19,12 +36,13 @@
const char kDeviceName[] = "testdevice";
} // namespace {}
-class DeviceTest : public Test {
+class DeviceTest : public PropertyStoreTest {
public:
DeviceTest()
: device_(new Device(&control_interface_, NULL, NULL, kDeviceName, 0)) {
DHCPProvider::GetInstance()->glib_ = &glib_;
}
+ virtual ~DeviceTest() {}
protected:
MockGLib glib_;
@@ -32,6 +50,57 @@
DeviceRefPtr device_;
};
+TEST_F(DeviceTest, Contains) {
+ EXPECT_TRUE(device_->Contains(flimflam::kNameProperty));
+ EXPECT_FALSE(device_->Contains(""));
+}
+
+TEST_F(DeviceTest, Dispatch) {
+ ::DBus::Error error;
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(device_.get(),
+ flimflam::kPoweredProperty,
+ bool_v_,
+ error));
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(
+ device_.get(),
+ flimflam::kBgscanSignalThresholdProperty,
+ int32_v_,
+ error));
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(device_.get(),
+ flimflam::kScanIntervalProperty,
+ uint16_v_,
+ error));
+
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(device_.get(), "", byte_v_, error));
+ EXPECT_EQ(invalid_prop_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(device_.get(),
+ "",
+ stringmap_v_,
+ error));
+ EXPECT_EQ(invalid_prop_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(device_.get(),
+ "",
+ uint32_v_,
+ error));
+ EXPECT_EQ(invalid_prop_, error.name());
+
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(device_.get(),
+ flimflam::kCarrierProperty,
+ string_v_,
+ error));
+ EXPECT_EQ(invalid_args_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(device_.get(),
+ flimflam::kNetworksProperty,
+ strings_v_,
+ error));
+ EXPECT_EQ(invalid_args_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(device_.get(),
+ flimflam::kPRLVersionProperty,
+ int16_v_,
+ error));
+ EXPECT_EQ(invalid_args_, error.name());
+}
+
TEST_F(DeviceTest, TechnologyIs) {
EXPECT_FALSE(device_->TechnologyIs(Device::kEthernet));
}
diff --git a/error.h b/error.h
index 6548467..cf04a3b 100644
--- a/error.h
+++ b/error.h
@@ -31,6 +31,7 @@
kPinError,
kNumErrors
};
+ static const char * const kErrorNames[kNumErrors];
Error(Type type, const std::string& message);
virtual ~Error();
@@ -40,8 +41,6 @@
void ToDBusError(::DBus::Error *error);
private:
- static const char * const kErrorNames[kNumErrors];
-
Type type_;
std::string message_;
diff --git a/ethernet_service.cc b/ethernet_service.cc
index b3e31f7..fe04655 100644
--- a/ethernet_service.cc
+++ b/ethernet_service.cc
@@ -12,6 +12,7 @@
#include <string>
#include <base/logging.h>
+#include <chromeos/dbus/service_constants.h>
#include "shill/control_interface.h"
#include "shill/device.h"
@@ -29,8 +30,11 @@
Ethernet *device,
const string &name)
: Service(control_interface, dispatcher, device, name),
- ethernet_(device) {
+ ethernet_(device),
+ type_(flimflam::kTypeEthernet) {
set_auto_connect(true);
+
+ RegisterConstString(flimflam::kTypeProperty, &type_);
}
EthernetService::~EthernetService() { }
diff --git a/ethernet_service.h b/ethernet_service.h
index 9478691..1886854 100644
--- a/ethernet_service.h
+++ b/ethernet_service.h
@@ -26,8 +26,13 @@
~EthernetService();
void Connect();
void Disconnect();
+
+ protected:
+ virtual std::string CalculateState() { return "idle"; }
+
private:
Ethernet *ethernet_;
+ const std::string type_;
DISALLOW_COPY_AND_ASSIGN(EthernetService);
};
diff --git a/manager.cc b/manager.cc
index fab11b0..b19268d 100644
--- a/manager.cc
+++ b/manager.cc
@@ -11,6 +11,7 @@
#include <base/logging.h>
#include <base/memory/ref_counted.h>
+#include <chromeos/dbus/service_constants.h>
#include "shill/adaptor_interfaces.h"
#include "shill/control_interface.h"
@@ -29,8 +30,24 @@
EventDispatcher *dispatcher)
: adaptor_(control_interface->CreateManagerAdaptor(this)),
device_info_(control_interface, dispatcher, this),
- running_(false) {
+ running_(false),
+ offline_mode_(false),
+ state_(flimflam::kStateOffline) {
// Initialize Interface monitor, so we can detect new interfaces
+ known_properties_.push_back(flimflam::kStateProperty);
+ known_properties_.push_back(flimflam::kAvailableTechnologiesProperty);
+ known_properties_.push_back(flimflam::kEnabledTechnologiesProperty);
+ known_properties_.push_back(flimflam::kConnectedTechnologiesProperty);
+ known_properties_.push_back(flimflam::kDefaultTechnologyProperty);
+ known_properties_.push_back(flimflam::kCheckPortalListProperty);
+ known_properties_.push_back(flimflam::kCountryProperty);
+ known_properties_.push_back(flimflam::kOfflineModeProperty);
+ known_properties_.push_back(flimflam::kPortalURLProperty);
+ known_properties_.push_back(flimflam::kActiveProfileProperty);
+ known_properties_.push_back(flimflam::kProfilesProperty);
+ known_properties_.push_back(flimflam::kDevicesProperty);
+ known_properties_.push_back(flimflam::kServicesProperty);
+ known_properties_.push_back(flimflam::kServiceWatchListProperty);
VLOG(2) << "Manager initialized.";
}
@@ -110,18 +127,49 @@
return NULL;
}
+bool Manager::Contains(const std::string &property) {
+ vector<string>::iterator it;
+ for (it = known_properties_.begin(); it != known_properties_.end(); ++it) {
+ if (property == *it)
+ return true;
+ }
+ return false;
+}
+
bool Manager::SetBoolProperty(const string& name, bool value, Error *error) {
VLOG(2) << "Setting " << name << " as a bool.";
- // TODO(cmasone): Set actual properties.
- return true;
+ bool set = false;
+ if (name == flimflam::kOfflineModeProperty) {
+ offline_mode_ = value;
+ set = true;
+ }
+ if (!set && error)
+ error->Populate(Error::kInvalidArguments, name + " is not a R/W bool.");
+ return set;
}
bool Manager::SetStringProperty(const string& name,
const string& value,
Error *error) {
VLOG(2) << "Setting " << name << " as a string.";
- // TODO(cmasone): Set actual properties.
- return true;
+ bool set = false;
+ if (name == flimflam::kActiveProfileProperty) {
+ active_profile_ = value;
+ set = true;
+ } else if (name == flimflam::kCountryProperty) {
+ country_ = value;
+ set = true;
+ } else if (name == flimflam::kPortalURLProperty) {
+ portal_url_ = value;
+ set = true;
+ } else if (name == flimflam::kCheckPortalListProperty) {
+ // parse string, update all services of specified technologies.
+ set = true;
+ }
+
+ if (!set && error)
+ error->Populate(Error::kInvalidArguments, name + " is not a R/W string.");
+ return set;
}
} // namespace shill
diff --git a/manager.h b/manager.h
index 58d4407..bcfe6b4 100644
--- a/manager.h
+++ b/manager.h
@@ -29,7 +29,7 @@
// A constructor for the Manager object
Manager(ControlInterface *control_interface,
EventDispatcher *dispatcher);
- ~Manager();
+ virtual ~Manager();
void Start();
void Stop();
@@ -45,18 +45,31 @@
ServiceRefPtr FindService(const std::string& name);
// Implementation of PropertyStoreInterface
- bool SetBoolProperty(const std::string& name, bool value, Error *error);
-
- bool SetStringProperty(const std::string& name,
- const std::string& value,
- Error *error);
+ virtual bool Contains(const std::string &property);
+ virtual bool SetBoolProperty(const std::string &name,
+ bool value,
+ Error *error);
+ virtual bool SetStringProperty(const std::string &name,
+ const std::string &value,
+ Error *error);
private:
scoped_ptr<ManagerAdaptorInterface> adaptor_;
DeviceInfo device_info_;
bool running_;
+ std::vector<std::string> known_properties_;
std::vector<DeviceRefPtr> devices_;
std::vector<ServiceRefPtr> services_;
+
+ // Properties to be get/set via PropertyStoreInterface calls.
+ bool offline_mode_;
+ std::string state_;
+ std::string country_;
+ std::string portal_url_;
+
+ std::string active_profile_; // This is supposed to be, essentially,
+ // an RPC-visible object handle
+
friend class ManagerAdaptorInterface;
};
diff --git a/manager_dbus_adaptor.cc b/manager_dbus_adaptor.cc
index b53dc5f..91cd9f5 100644
--- a/manager_dbus_adaptor.cc
+++ b/manager_dbus_adaptor.cc
@@ -66,7 +66,9 @@
void ManagerDBusAdaptor::SetProperty(const string &name,
const ::DBus::Variant &value,
::DBus::Error &error) {
- DBusAdaptor::DispatchOnType(manager_, name, value, error);
+ if (DBusAdaptor::DispatchOnType(manager_, name, value, error)) {
+ PropertyChanged(name, value);
+ }
}
string ManagerDBusAdaptor::GetState(::DBus::Error &error) {
diff --git a/manager_unittest.cc b/manager_unittest.cc
index 26a1ed9..74a88c3 100644
--- a/manager_unittest.cc
+++ b/manager_unittest.cc
@@ -1,19 +1,29 @@
// Copyright (c) 2011 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 "shill/manager.h"
+
#include <glib.h>
#include <base/callback_old.h>
#include <base/logging.h>
#include <base/memory/ref_counted.h>
#include <base/message_loop.h>
+#include <chromeos/dbus/service_constants.h>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "shill/mock_control.h"
-#include "shill/manager.h"
#include "shill/mock_device.h"
#include "shill/mock_service.h"
+#include "shill/property_store_unittest.h"
+#include "shill/shill_event.h"
+
+using std::map;
+using std::string;
+using std::vector;
+
namespace shill {
using ::testing::Test;
@@ -22,12 +32,10 @@
using ::testing::Return;
using std::vector;
-class ManagerTest : public Test {
+class ManagerTest : public PropertyStoreTest {
public:
- ManagerTest()
- : manager_(&control_, &dispatcher_),
- factory_(this) {
- }
+ ManagerTest() : factory_(this) {}
+ virtual ~ManagerTest() {}
bool IsDeviceRegistered(Device *device, Device::Technology tech) {
vector<DeviceRefPtr> devices;
@@ -36,26 +44,30 @@
}
protected:
- MockControl control_;
- Manager manager_;
- EventDispatcher dispatcher_;
ScopedRunnableMethodFactory<ManagerTest> factory_;
};
+TEST_F(ManagerTest, Contains) {
+ EXPECT_TRUE(manager_.Contains(flimflam::kStateProperty));
+ EXPECT_FALSE(manager_.Contains(""));
+}
+
TEST_F(ManagerTest, DeviceRegistration) {
- scoped_refptr<MockDevice> mock_device(new NiceMock<MockDevice>(&control_,
- &dispatcher_,
- &manager_,
- "null0",
- -1));
+ scoped_refptr<MockDevice> mock_device(
+ new NiceMock<MockDevice>(&control_interface_,
+ &dispatcher_,
+ &manager_,
+ "null0",
+ -1));
ON_CALL(*mock_device.get(), TechnologyIs(Device::kEthernet))
.WillByDefault(Return(true));
- scoped_refptr<MockDevice> mock_device2(new NiceMock<MockDevice>(&control_,
- &dispatcher_,
- &manager_,
- "null1",
- -1));
+ scoped_refptr<MockDevice> mock_device2(
+ new NiceMock<MockDevice>(&control_interface_,
+ &dispatcher_,
+ &manager_,
+ "null1",
+ -1));
ON_CALL(*mock_device2.get(), TechnologyIs(Device::kWifi))
.WillByDefault(Return(true));
@@ -67,19 +79,21 @@
}
TEST_F(ManagerTest, DeviceDeregistration) {
- scoped_refptr<MockDevice> mock_device(new NiceMock<MockDevice>(&control_,
- &dispatcher_,
- &manager_,
- "null2",
- -1));
+ scoped_refptr<MockDevice> mock_device(
+ new NiceMock<MockDevice>(&control_interface_,
+ &dispatcher_,
+ &manager_,
+ "null2",
+ -1));
ON_CALL(*mock_device.get(), TechnologyIs(Device::kEthernet))
.WillByDefault(Return(true));
- scoped_refptr<MockDevice> mock_device2(new NiceMock<MockDevice>(&control_,
- &dispatcher_,
- &manager_,
- "null2",
- -1));
+ scoped_refptr<MockDevice> mock_device2(
+ new NiceMock<MockDevice>(&control_interface_,
+ &dispatcher_,
+ &manager_,
+ "null2",
+ -1));
ON_CALL(*mock_device2.get(), TechnologyIs(Device::kWifi))
.WillByDefault(Return(true));
@@ -97,7 +111,7 @@
}
TEST_F(ManagerTest, ServiceRegistration) {
- scoped_refptr<MockDevice> device(new MockDevice(&control_,
+ scoped_refptr<MockDevice> device(new MockDevice(&control_interface_,
&dispatcher_,
&manager_,
"null3",
@@ -105,13 +119,13 @@
const char kService1[] = "service1";
const char kService2[] = "wifi_service2";
scoped_refptr<MockService> mock_service(
- new NiceMock<MockService>(&control_,
+ new NiceMock<MockService>(&control_interface_,
&dispatcher_,
device.get(),
kService1));
scoped_refptr<MockService> mock_service2(
- new NiceMock<MockService>(&control_,
+ new NiceMock<MockService>(&control_interface_,
&dispatcher_,
device.get(),
kService2));
@@ -123,4 +137,44 @@
EXPECT_TRUE(manager_.FindService(kService2).get() != NULL);
}
+TEST_F(ManagerTest, Dispatch) {
+ ::DBus::Error error;
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(&manager_,
+ flimflam::kOfflineModeProperty,
+ bool_v_,
+ error));
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(&manager_,
+ flimflam::kActiveProfileProperty,
+ string_v_,
+ error));
+
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_, "", bool_v_, error));
+ EXPECT_EQ(invalid_prop_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_, "", strings_v_, error));
+ EXPECT_EQ(invalid_prop_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_, "", int16_v_, error));
+ EXPECT_EQ(invalid_prop_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_, "", int32_v_, error));
+ EXPECT_EQ(invalid_prop_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_, "", uint16_v_, error));
+ EXPECT_EQ(invalid_prop_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_, "", uint32_v_, error));
+ EXPECT_EQ(invalid_prop_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_, "", stringmap_v_, error));
+ EXPECT_EQ(invalid_prop_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_, "", byte_v_, error));
+ EXPECT_EQ(invalid_prop_, error.name());
+
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_,
+ flimflam::kActiveProfileProperty,
+ bool_v_,
+ error));
+ EXPECT_EQ(invalid_args_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(&manager_,
+ flimflam::kOfflineModeProperty,
+ string_v_,
+ error));
+ EXPECT_EQ(invalid_args_, error.name());
+}
+
} // namespace shill
diff --git a/mock_property_store.h b/mock_property_store.h
new file mode 100644
index 0000000..4971984
--- /dev/null
+++ b/mock_property_store.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2011 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.
+
+#ifndef SHILL_MOCK_PROPERTY_STORE_
+#define SHILL_MOCK_PROPERTY_STORE_
+
+#include "shill/property_store_interface.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <base/basictypes.h>
+
+namespace shill {
+
+class Error;
+
+class MockPropertyStore : public PropertyStoreInterface {
+ public:
+ MockPropertyStore() {}
+ virtual ~MockPropertyStore() {}
+ MOCK_METHOD1(Contains, bool(const std::string&));
+ MOCK_METHOD3(SetBoolProperty, bool(const std::string&, bool, Error*));
+ MOCK_METHOD3(SetInt16Property, bool(const std::string&, int16, Error*));
+ MOCK_METHOD3(SetInt32Property, bool(const std::string&, int32, Error*));
+ MOCK_METHOD3(SetStringProperty, bool(const std::string&,
+ const std::string&,
+ Error*));
+ MOCK_METHOD3(SetStringmapProperty,
+ bool(const std::string&,
+ const std::map<std::string, std::string>&,
+ Error*));
+ MOCK_METHOD3(SetStringsProperty, bool(const std::string&,
+ const std::vector<std::string>&,
+ Error*));
+ MOCK_METHOD3(SetUint8Property, bool(const std::string&, uint8, Error*));
+ MOCK_METHOD3(SetUint16Property, bool(const std::string&, uint16, Error*));
+ MOCK_METHOD3(SetUint32Property, bool(const std::string&, uint32, Error*));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockPropertyStore);
+};
+
+} // namespace shill
+
+#endif // SHILL_MOCK_PROPERTY_STORE_
diff --git a/mock_service.h b/mock_service.h
index 80cf1d8..78e766e 100644
--- a/mock_service.h
+++ b/mock_service.h
@@ -26,6 +26,7 @@
MOCK_METHOD0(Connect, void(void));
MOCK_METHOD0(Disconnect, void(void));
+ MOCK_METHOD0(CalculateState, std::string(void));
private:
DISALLOW_COPY_AND_ASSIGN(MockService);
diff --git a/property_accessor.h b/property_accessor.h
new file mode 100644
index 0000000..cb39182
--- /dev/null
+++ b/property_accessor.h
@@ -0,0 +1,96 @@
+// Copyright (c) 2011 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.
+
+#ifndef SHILL_PROPERTY_ACCESSOR_
+#define SHILL_PROPERTY_ACCESSOR_
+
+#include <base/basictypes.h>
+
+#include "shill/accessor_interface.h"
+
+namespace shill {
+
+// Templated implementations of AccessorInterface<>.
+// PropertyAccessor<> and ConstPropertyAccessor<> respectively provide
+// R/W and R/O access to the value pointed to by |property|.
+// this allows a class to easily map strings to member variables, so that
+// pieces of state stored in the class can be queried or updated by name.
+//
+// bool foo = true;
+// map<string, BoolAccessor> accessors;
+// accessors["foo"] = BoolAccessor(new PropertyAccessor<bool>(&foo));
+// bool new_foo = accessors["foo"]->Get(); // new_foo == true
+// accessors["foo"]->Set(false); // returns true, because setting is allowed.
+// // foo == false, new_foo == true
+// new_foo = accessors["foo"]->Get(); // new_foo == false
+template <class T>
+class PropertyAccessor : public AccessorInterface<T> {
+ public:
+ explicit PropertyAccessor(T *property) : property_(property) {
+ DCHECK(property);
+ }
+ virtual ~PropertyAccessor() {}
+
+ const T &Get() { return *property_; }
+ bool Set(const T &value) {
+ *property_ = value;
+ return true;
+ }
+
+ private:
+ T * const property_;
+ DISALLOW_COPY_AND_ASSIGN(PropertyAccessor);
+};
+
+template <class T>
+class ConstPropertyAccessor : public AccessorInterface<T> {
+ public:
+ explicit ConstPropertyAccessor(const T *property) : property_(property) {
+ DCHECK(property);
+ }
+ virtual ~ConstPropertyAccessor() {}
+
+ const T &Get() { return *property_; }
+ bool Set(const T &value) { return false; }
+
+ private:
+ const T * const property_;
+ DISALLOW_COPY_AND_ASSIGN(ConstPropertyAccessor);
+};
+
+// CustomAccessor<> allows custom getter and setter methods to be provided.
+// Thus, if the state to be returned is to be derived on-demand, we can
+// still fit it into the AccessorInterface<> framework.
+template<class C, class T>
+class CustomAccessor : public AccessorInterface<T> {
+ public:
+ // |target| is the object on which to call the methods |getter| and |setter|
+ // |setter| is allowed to be NULL, in which case we will simply reject
+ // attempts to set via the accessor.
+ // It is an error to pass NULL for either of the other two arguments.
+ CustomAccessor(C *target, T(C::*getter)(), bool(C::*setter)(const T&))
+ : target_(target),
+ getter_(getter),
+ setter_(setter) {
+ DCHECK(target);
+ DCHECK(getter);
+ }
+ virtual ~CustomAccessor() {}
+
+ const T &Get() { return storage_ = (target_->*getter_)(); }
+ bool Set(const T &value) { return setter_ && (target_->*setter_)(value); }
+
+ private:
+ C * const target_;
+ // Get() returns a const&, so we need to have internal storage to which to
+ // return a reference.
+ T storage_;
+ T(C::*getter_)(void);
+ bool(C::*setter_)(const T&);
+ DISALLOW_COPY_AND_ASSIGN(CustomAccessor);
+};
+
+} // namespace shill
+
+#endif // SHILL_PROPERTY_ACCESSOR_
diff --git a/property_store_interface.h b/property_store_interface.h
index 585c531..c766d77 100644
--- a/property_store_interface.h
+++ b/property_store_interface.h
@@ -19,6 +19,8 @@
public:
virtual ~PropertyStoreInterface();
+ virtual bool Contains(const std::string& property) = 0;
+
// Methods to allow the setting, by name, of properties stored in this object.
// The property names are declared in chromeos/dbus/service_constants.h,
// so that they may be shared with libcros.
diff --git a/property_store_unittest.h b/property_store_unittest.h
new file mode 100644
index 0000000..9e7ba6e
--- /dev/null
+++ b/property_store_unittest.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2011 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.
+
+#ifndef SHILL_PROPERTY_STORE_UNITTEST_H_
+#define SHILL_PROPERTY_STORE_UNITTEST_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <dbus-c++/dbus.h>
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+#include "shill/dbus_adaptor.h"
+#include "shill/error.h"
+#include "shill/manager.h"
+#include "shill/mock_control.h"
+#include "shill/property_store_interface.h"
+#include "shill/shill_event.h"
+
+namespace shill {
+
+class PropertyStoreTest : public ::testing::Test {
+ public:
+ PropertyStoreTest()
+ : bool_v_(DBusAdaptor::BoolToVariant(0)),
+ byte_v_(DBusAdaptor::ByteToVariant(0)),
+ uint16_v_(DBusAdaptor::Uint16ToVariant(0)),
+ uint32_v_(DBusAdaptor::Uint32ToVariant(0)),
+ int16_v_(DBusAdaptor::Int16ToVariant(0)),
+ int32_v_(DBusAdaptor::Int32ToVariant(0)),
+ string_v_(DBusAdaptor::StringToVariant("")),
+ stringmap_v_(DBusAdaptor::StringmapToVariant(
+ std::map<std::string, std::string>())),
+ strings_v_(DBusAdaptor::StringsToVariant(
+ std::vector<std::string>(1, ""))),
+ manager_(&control_interface_, &dispatcher_),
+ invalid_args_(Error::kErrorNames[Error::kInvalidArguments]),
+ invalid_prop_(Error::kErrorNames[Error::kInvalidProperty]) {
+ }
+
+ virtual ~PropertyStoreTest() {}
+
+ protected:
+ ::DBus::Variant bool_v_;
+ ::DBus::Variant byte_v_;
+ ::DBus::Variant uint16_v_;
+ ::DBus::Variant uint32_v_;
+ ::DBus::Variant int16_v_;
+ ::DBus::Variant int32_v_;
+ ::DBus::Variant string_v_;
+ ::DBus::Variant stringmap_v_;
+ ::DBus::Variant strings_v_;
+
+ MockControl control_interface_;
+ EventDispatcher dispatcher_;
+ Manager manager_;
+ std::string invalid_args_;
+ std::string invalid_prop_;
+};
+
+} // namespace shill
+#endif // SHILL_PROPERTY_STORE_UNITTEST_H_
diff --git a/service.cc b/service.cc
index 60e5ae4..82951ec 100644
--- a/service.cc
+++ b/service.cc
@@ -10,10 +10,13 @@
#include <vector>
#include <base/logging.h>
+#include <base/memory/scoped_ptr.h>
+#include <chromeos/dbus/service_constants.h>
#include "shill/control_interface.h"
#include "shill/device_config_interface.h"
#include "shill/error.h"
+#include "shill/property_accessor.h"
#include "shill/service.h"
#include "shill/service_dbus_adaptor.h"
@@ -26,57 +29,165 @@
EventDispatcher *dispatcher,
DeviceConfigInterfaceRefPtr config_interface,
const string& name)
- : dispatcher_(dispatcher),
+ : auto_connect_(false),
+ connectable_(false),
+ favorite_(false),
+ priority_(0),
+ save_credentials_(true),
+ dispatcher_(dispatcher),
name_(name),
available_(false),
configured_(false),
- auto_connect_(false),
configuration_(NULL),
connection_(NULL),
config_interface_(config_interface),
adaptor_(control_interface->CreateServiceAdaptor(this)) {
- // Initialize Interface montior, so we can detect new interfaces
+
+ RegisterBool(flimflam::kAutoConnectProperty, &auto_connect_);
+ RegisterString(flimflam::kCheckPortalProperty, &check_portal_);
+ RegisterConstBool(flimflam::kConnectableProperty, &connectable_);
+ RegisterDerivedString(flimflam::kDeviceProperty, &Service::DeviceRPCID, NULL);
+
+ RegisterString(flimflam::kEapIdentityProperty, &eap_.identity);
+ RegisterString(flimflam::kEAPEAPProperty, &eap_.eap);
+ RegisterString(flimflam::kEapPhase2AuthProperty, &eap_.inner_eap);
+ RegisterString(flimflam::kEapAnonymousIdentityProperty,
+ &eap_.anonymous_identity);
+ RegisterString(flimflam::kEAPClientCertProperty, &eap_.client_cert);
+ RegisterString(flimflam::kEAPCertIDProperty, &eap_.cert_id);
+ RegisterString(flimflam::kEapPrivateKeyProperty, &eap_.private_key);
+ RegisterString(flimflam::kEapPrivateKeyPasswordProperty,
+ &eap_.private_key_password);
+ RegisterString(flimflam::kEAPKeyIDProperty, &eap_.key_id);
+ RegisterString(flimflam::kEapCaCertProperty, &eap_.ca_cert);
+ RegisterString(flimflam::kEapCaCertIDProperty, &eap_.ca_cert_id);
+ RegisterString(flimflam::kEAPPINProperty, &eap_.pin);
+ RegisterString(flimflam::kEapPasswordProperty, &eap_.password);
+ RegisterString(flimflam::kEapKeyMgmtProperty, &eap_.key_management);
+ RegisterBool(flimflam::kEapUseSystemCAsProperty, &eap_.use_system_cas);
+
+ RegisterConstString(flimflam::kErrorProperty, &error_);
+ RegisterConstBool(flimflam::kFavoriteProperty, &favorite_);
+ RegisterDerivedBool(flimflam::kIsActiveProperty, &Service::IsActive, NULL);
+ RegisterConstString(flimflam::kNameProperty, &name_);
+ RegisterInt32(flimflam::kPriorityProperty, &priority_);
+ RegisterDerivedString(flimflam::kProfileProperty,
+ &Service::ProfileRPCID,
+ NULL);
+ RegisterString(flimflam::kProxyConfigProperty, &proxy_config_);
+ RegisterBool(flimflam::kSaveCredentialsProperty, &save_credentials_);
+ RegisterDerivedString(flimflam::kStateProperty,
+ &Service::CalculateState,
+ NULL);
+
+ // TODO(cmasone): Create VPN Service with this property
+ // RegisterConstStringmap(flimflam::kProviderProperty, &provider_);
+
+ // TODO(cmasone): Add support for R/O properties that return DBus object paths
+ // flimflam::kDeviceProperty, flimflam::kProfileProperty
+
VLOG(2) << "Service initialized.";
}
Service::~Service() {}
-bool Service::SetBoolProperty(const string& name, bool value, Error *error) {
- VLOG(2) << "Setting " << name << " as a bool.";
- // TODO(cmasone): Set actual properties.
- return true;
+bool Service::Contains(const string &property) {
+ return (bool_properties_.find(property) != bool_properties_.end() ||
+ int32_properties_.find(property) != int32_properties_.end() ||
+ string_properties_.find(property) != string_properties_.end());
}
-bool Service::SetInt32Property(const std::string& name,
- int32 value,
- Error *error) {
- VLOG(2) << "Setting " << name << " as an int32.";
- // TODO(cmasone): Set actual properties.
- return true;
+bool Service::SetBoolProperty(const string& name, bool value, Error *error) {
+ VLOG(2) << "Setting " << name << " as a bool.";
+ bool set = bool_properties_[name]->Set(value);
+ if (!set && error)
+ error->Populate(Error::kInvalidArguments, name + " is not a R/W bool.");
+ return set;
+}
+
+bool Service::SetInt32Property(const string& name, int32 value, Error *error) {
+ VLOG(2) << "Setting " << name << " as an int32";
+ bool set = int32_properties_[name]->Set(value);
+ if (!set && error)
+ error->Populate(Error::kInvalidArguments, name + " is not a R/W int32.");
+ return set;
}
bool Service::SetStringProperty(const string& name,
const string& value,
Error *error) {
VLOG(2) << "Setting " << name << " as a string.";
- // TODO(cmasone): Set actual properties.
- return true;
+ bool set = string_properties_[name]->Set(value);
+ if (!set && error)
+ error->Populate(Error::kInvalidArguments, name + " is not a R/W string.");
+ return set;
}
bool Service::SetStringmapProperty(const string& name,
- const std::map<string, string>& values,
+ const map<string, string>& value,
Error *error) {
- VLOG(2) << "Setting " << name << " as a map of string:string";
- // TODO(cmasone): Set actual properties.
- return true;
+ VLOG(2) << "Setting " << name << " as a string map.";
+ bool set = stringmap_properties_[name]->Set(value);
+ if (!set && error)
+ error->Populate(Error::kInvalidArguments, name + " is not a R/W strmap.");
+ return set;
}
-bool Service::SetUint8Property(const std::string& name,
- uint8 value,
- Error *error) {
- VLOG(2) << "Setting " << name << " as a uint8.";
- // TODO(cmasone): Set actual properties.
- return true;
+void Service::RegisterBool(const string &name, bool *prop) {
+ bool_properties_[name] = BoolAccessor(new PropertyAccessor<bool>(prop));
+}
+
+void Service::RegisterConstBool(const string &name, const bool *prop) {
+ bool_properties_[name] = BoolAccessor(new ConstPropertyAccessor<bool>(prop));
+}
+
+void Service::RegisterDerivedBool(const string &name,
+ bool(Service::*get)(void),
+ bool(Service::*set)(const bool&)) {
+ bool_properties_[name] =
+ BoolAccessor(new CustomAccessor<Service, bool>(this, get, set));
+}
+
+void Service::RegisterInt32(const string &name, int32 *prop) {
+ int32_properties_[name] = Int32Accessor(new PropertyAccessor<int32>(prop));
+}
+
+void Service::RegisterString(const string &name, string *prop) {
+ string_properties_[name] = StringAccessor(new PropertyAccessor<string>(prop));
+}
+
+void Service::RegisterConstString(const string &name, const string *prop) {
+ string_properties_[name] =
+ StringAccessor(new ConstPropertyAccessor<string>(prop));
+}
+
+void Service::RegisterDerivedString(const string &name,
+ string(Service::*get)(void),
+ bool(Service::*set)(const string&)) {
+ string_properties_[name] =
+ StringAccessor(new CustomAccessor<Service, string>(this, get, set));
+}
+
+void Service::RegisterStringmap(const string &name,
+ map<string, string> *prop) {
+ stringmap_properties_[name] =
+ StringmapAccessor(new PropertyAccessor<map<string, string> >(prop));
+}
+
+void Service::RegisterConstStringmap(const string &name,
+ const map<string, string> *prop) {
+ stringmap_properties_[name] =
+ StringmapAccessor(new ConstPropertyAccessor<map<string, string> >(prop));
+}
+
+void Service::RegisterConstUint8(const string &name, const uint8 *prop) {
+ uint8_properties_[name] =
+ Uint8Accessor(new ConstPropertyAccessor<uint8>(prop));
+}
+
+void Service::RegisterConstUint16(const string &name, const uint16 *prop) {
+ uint16_properties_[name] =
+ Uint16Accessor(new ConstPropertyAccessor<uint16>(prop));
}
} // namespace shill
diff --git a/service.h b/service.h
index 0cd0107..3c7be8c 100644
--- a/service.h
+++ b/service.h
@@ -9,10 +9,13 @@
#include <map>
#include <vector>
+
+#include <base/hash_tables.h>
#include <base/memory/ref_counted.h>
#include <base/memory/scoped_ptr.h>
#include "shill/device_config_interface.h"
+#include "shill/accessor_interface.h"
#include "shill/property_store_interface.h"
namespace shill {
@@ -53,6 +56,24 @@
kServiceStateDisconnected,
kServiceStateFailure
};
+ struct EapCredentials {
+ EapCredentials() : use_system_cas(false) {}
+ std::string identity;
+ std::string eap;
+ std::string inner_eap;
+ std::string anonymous_identity;
+ std::string client_cert;
+ std::string cert_id;
+ std::string private_key;
+ std::string private_key_password;
+ std::string key_id;
+ std::string ca_cert;
+ std::string ca_cert_id;
+ bool use_system_cas;
+ std::string pin;
+ std::string password;
+ std::string key_management;
+ };
// A constructor for the Service object
Service(ControlInterface *control_interface,
@@ -63,16 +84,23 @@
virtual void Connect() = 0;
virtual void Disconnect() = 0;
+ virtual bool IsActive() { return false; }
+
// Implementation of PropertyStoreInterface
- bool SetBoolProperty(const std::string& name, bool value, Error *error);
- bool SetInt32Property(const std::string& name, int32 value, Error *error);
- bool SetStringProperty(const std::string& name,
- const std::string& value,
- Error *error);
- bool SetStringmapProperty(const std::string& name,
- const std::map<std::string, std::string>& values,
- Error *error);
- bool SetUint8Property(const std::string& name, uint8 value, Error *error);
+ virtual bool Contains(const std::string &property);
+ virtual bool SetBoolProperty(const std::string &name,
+ bool value,
+ Error *error);
+ virtual bool SetInt32Property(const std::string &name,
+ int32 value,
+ Error *error);
+ virtual bool SetStringProperty(const std::string &name,
+ const std::string &value,
+ Error *error);
+ virtual bool SetStringmapProperty(
+ const std::string &name,
+ const std::map<std::string, std::string> &values,
+ Error *error);
// Returns a string that is guaranteed to uniquely identify this
// Service instance.
@@ -82,18 +110,63 @@
void set_auto_connect(bool connect) { auto_connect_ = connect; }
protected:
+ virtual std::string CalculateState() = 0;
+
+ void RegisterBool(const std::string &name, bool *prop);
+ void RegisterConstBool(const std::string &name, const bool *prop);
+ void RegisterDerivedBool(const std::string &name,
+ bool(Service::*get)(void),
+ bool(Service::*set)(const bool&));
+ void RegisterInt32(const std::string &name, int32 *prop);
+ void RegisterString(const std::string &name, std::string *prop);
+ void RegisterConstString(const std::string &name, const std::string *prop);
+ void RegisterDerivedString(const std::string &name,
+ std::string(Service::*get)(void),
+ bool(Service::*set)(const std::string&));
+ void RegisterStringmap(const std::string &name,
+ std::map<std::string, std::string> *prop);
+ void RegisterConstStringmap(const std::string &name,
+ const std::map<std::string, std::string> *prop);
+ void RegisterConstUint8(const std::string &name, const uint8 *prop);
+ void RegisterConstUint16(const std::string &name, const uint16 *prop);
+
+ base::hash_map<std::string, BoolAccessor> bool_properties_;
+ base::hash_map<std::string, Int32Accessor> int32_properties_;
+ base::hash_map<std::string, StringAccessor> string_properties_;
+ base::hash_map<std::string, StringmapAccessor> stringmap_properties_;
+ base::hash_map<std::string, Uint8Accessor> uint8_properties_;
+ base::hash_map<std::string, Uint16Accessor> uint16_properties_;
+
+ // Properties
+ bool auto_connect_;
+ std::string check_portal_;
+ bool connectable_;
+ EapCredentials eap_;
+ std::string error_;
+ bool favorite_;
+ int32 priority_;
+ std::string proxy_config_;
+ bool save_credentials_;
+
EventDispatcher *dispatcher_;
private:
+ std::string DeviceRPCID() {
+ return ""; // Will need to call Device to get this.
+ }
+ std::string ProfileRPCID() {
+ return ""; // Will need to call Profile to get this.
+ }
+
const std::string name_;
bool available_;
bool configured_;
- bool auto_connect_;
Configuration *configuration_;
Connection *connection_;
DeviceConfigInterfaceRefPtr config_interface_;
Endpoint *endpoint_;
scoped_ptr<ServiceAdaptorInterface> adaptor_;
+
friend class ServiceAdaptorInterface;
DISALLOW_COPY_AND_ASSIGN(Service);
};
diff --git a/service_unittest.cc b/service_unittest.cc
new file mode 100644
index 0000000..a3be06f
--- /dev/null
+++ b/service_unittest.cc
@@ -0,0 +1,91 @@
+// Copyright (c) 2011 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 "shill/service.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <dbus-c++/dbus.h>
+#include <chromeos/dbus/service_constants.h>
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+#include "shill/dbus_adaptor.h"
+#include "shill/ethernet_service.h"
+#include "shill/manager.h"
+#include "shill/mock_control.h"
+#include "shill/mock_device.h"
+#include "shill/mock_service.h"
+#include "shill/property_store_unittest.h"
+#include "shill/shill_event.h"
+
+using std::map;
+using std::string;
+using std::vector;
+using ::testing::_;
+using ::testing::NiceMock;
+using ::testing::Return;
+using ::testing::Test;
+
+namespace shill {
+
+class ServiceTest : public PropertyStoreTest {
+ public:
+ ServiceTest() {}
+ virtual ~ServiceTest() {}
+};
+
+TEST_F(ServiceTest, Dispatch) {
+ DeviceRefPtr device(new MockDevice(&control_interface_,
+ &dispatcher_,
+ &manager_,
+ "mock-device",
+ 0));
+ ServiceRefPtr service(new MockService(&control_interface_,
+ &dispatcher_,
+ device.get(),
+ "mock-service"));
+ ::DBus::Error error;
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(service.get(),
+ flimflam::kSaveCredentialsProperty,
+ bool_v_,
+ error));
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(service.get(),
+ flimflam::kPriorityProperty,
+ int32_v_,
+ error));
+ EXPECT_TRUE(DBusAdaptor::DispatchOnType(service.get(),
+ flimflam::kEAPEAPProperty,
+ string_v_,
+ error));
+
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(service.get(),
+ flimflam::kFavoriteProperty,
+ bool_v_,
+ error));
+ EXPECT_EQ(invalid_args_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(service.get(), "", int16_v_, error));
+ EXPECT_EQ(invalid_prop_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(service.get(), "", int32_v_, error));
+ EXPECT_EQ(invalid_prop_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(service.get(),
+ "",
+ uint16_v_,
+ error));
+ EXPECT_EQ(invalid_prop_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(service.get(),
+ "",
+ uint32_v_,
+ error));
+ EXPECT_EQ(invalid_prop_, error.name());
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(service.get(),
+ "",
+ strings_v_,
+ error));
+ EXPECT_EQ(invalid_prop_, error.name());
+}
+
+} // namespace shill
diff --git a/wifi.cc b/wifi.cc
index a42dce4..9298f6d 100644
--- a/wifi.cc
+++ b/wifi.cc
@@ -119,19 +119,19 @@
WiFi::WiFi(ControlInterface *control_interface,
EventDispatcher *dispatcher,
Manager *manager,
- const string& link_name,
+ const string& link,
int interface_index)
: Device(control_interface,
dispatcher,
manager,
- link_name,
+ link,
interface_index),
task_factory_(this),
control_interface_(control_interface),
dispatcher_(dispatcher),
dbus_(DBus::Connection::SystemBus()),
scan_pending_(false) {
- VLOG(2) << "WiFi device " << link_name << " initialized.";
+ VLOG(2) << "WiFi device " << link_name() << " initialized.";
}
WiFi::~WiFi() {
diff --git a/wifi.h b/wifi.h
index f7e851a..bdd4415 100644
--- a/wifi.h
+++ b/wifi.h
@@ -26,7 +26,7 @@
WiFi(ControlInterface *control_interface,
EventDispatcher *dispatcher,
Manager *manager,
- const std::string& link_name,
+ const std::string& link,
int interface_index);
virtual ~WiFi();
virtual void Start();
diff --git a/wifi_service.cc b/wifi_service.cc
index a12b111..614c67e 100644
--- a/wifi_service.cc
+++ b/wifi_service.cc
@@ -7,6 +7,7 @@
#include <string>
#include <base/logging.h>
+#include <chromeos/dbus/service_constants.h>
#include "shill/control_interface.h"
#include "shill/device.h"
@@ -31,8 +32,23 @@
task_factory_(this),
wifi_(device),
ssid_(ssid),
- mode_(mode),
- key_management_(key_management) {
+ mode_(mode) {
+ eap_.key_management = key_management;
+
+ // TODO(cmasone): Figure out if mode_ should be a string or what
+ // RegisterString(flimflam::kModeProperty, &mode_);
+ RegisterString(flimflam::kPassphraseProperty, &passphrase_);
+ RegisterBool(flimflam::kPassphraseRequiredProperty, &need_passphrase_);
+ RegisterConstString(flimflam::kSecurityProperty, &security_);
+
+ RegisterConstString(flimflam::kWifiAuthMode, &auth_mode_);
+ RegisterConstBool(flimflam::kWifiHiddenSsid, &hidden_ssid_);
+ RegisterConstUint16(flimflam::kWifiFrequency, &frequency_);
+ RegisterConstUint16(flimflam::kWifiPhyMode, &physical_mode_);
+ RegisterConstUint16(flimflam::kWifiHexSsid, &hex_ssid_);
+
+ RegisterConstUint8(flimflam::kSignalStrengthProperty, &strength_);
+ RegisterConstString(flimflam::kTypeProperty, &type_);
}
WiFiService::~WiFiService() {
@@ -48,6 +64,16 @@
task_factory_.NewRunnableMethod(&WiFiService::RealConnect));
}
+void WiFiService::Disconnect() {
+ // TODO(quiche) RemoveNetwork from supplicant
+ // XXX remove from favorite networks list?
+}
+
+bool WiFiService::Contains(const string &property) {
+ return (Service::Contains(property) ||
+ uint16_properties_.find(property) != uint16_properties_.end());
+}
+
void WiFiService::RealConnect() {
std::map<string, DBus::Variant> add_network_args;
DBus::MessageIter mi;
@@ -56,7 +82,7 @@
add_network_args[kSupplicantPropertyNetworkMode].writer().
append_uint32(mode_);
add_network_args[kSupplicantPropertyKeyMode].writer().
- append_string(key_management_.c_str());
+ append_string(eap_.key_management.c_str());
// TODO(quiche): figure out why we can't use operator<< without the
// temporary variable.
mi = add_network_args[kSupplicantPropertySSID].writer();
@@ -68,9 +94,4 @@
// XXX add to favorite networks list?
}
-void WiFiService::Disconnect() {
- // TODO(quiche) RemoveNetwork from supplicant
- // XXX remove from favorite networks list?
-}
-
} // namespace shill
diff --git a/wifi_service.h b/wifi_service.h
index fd5650a..e2cc2ad 100644
--- a/wifi_service.h
+++ b/wifi_service.h
@@ -28,6 +28,12 @@
void Connect();
void Disconnect();
+ // Implementation of PropertyStoreInterface
+ bool Contains(const std::string &property);
+
+ protected:
+ virtual std::string CalculateState() { return "idle"; }
+
private:
static const char kSupplicantPropertySSID[];
static const char kSupplicantPropertyNetworkMode[];
@@ -35,11 +41,24 @@
void RealConnect();
+ // Properties
+ std::string passphrase_;
+ bool need_passphrase_;
+ std::string security_;
+ uint8 strength_;
+ const std::string type_;
+ // TODO(cmasone): see if the below can be pulled from the endpoint associated
+ // with this service instead.
+ std::string auth_mode_;
+ bool hidden_ssid_;
+ uint16 frequency_;
+ uint16 physical_mode_;
+ uint16 hex_ssid_;
+
ScopedRunnableMethodFactory<WiFiService> task_factory_;
WiFi *wifi_;
const std::vector<uint8_t> ssid_;
uint32_t mode_;
- const std::string key_management_;
DISALLOW_COPY_AND_ASSIGN(WiFiService);
};