dhcp client: add RPC implementation part 1
This adds DBus rpc implementation for manager and service classes.
This follows the same rpc design convention as apmanager and shill.
While there, this also fixes a few typoes in comments.
Bug: 2564205
TEST=compile, and test using python scripts
Change-Id: I1157bdfbe6e84fbd898f146cd23e73ce8f027270
diff --git a/control_interface.h b/control_interface.h
new file mode 100644
index 0000000..f966123
--- /dev/null
+++ b/control_interface.h
@@ -0,0 +1,51 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef DHCP_CLIENT_CONTROL_INTERFACE_H_
+#define DHCP_CLIENT_CONTROL_INTERFACE_H_
+
+#include <base/callback.h>
+#include <base/macros.h>
+
+#include "dhcp_client/manager_adaptor_interface.h"
+#include "dhcp_client/service_adaptor_interface.h"
+
+namespace dhcp_client {
+
+class Manager;
+class Service;
+
+// This is the Interface for an object factory that creates adaptor/proxy
+// objects
+class ControlInterface {
+ public:
+ virtual ~ControlInterface() {}
+
+ virtual void Init() = 0;
+ virtual void Shutdown() = 0;
+
+ // Adaptor creation APIs.
+ virtual std::unique_ptr<ManagerAdaptorInterface> CreateManagerAdaptor(
+ Manager* manager) = 0;
+ virtual std::unique_ptr<ServiceAdaptorInterface> CreateServiceAdaptor(
+ Service* service) = 0;
+
+
+};
+
+} // namespace dhcp_client
+
+#endif // DHCP_CLIENT_CONTROL_INTERFACE_H_
diff --git a/daemon.cc b/daemon.cc
index ba3f1fd..a95ae92 100644
--- a/daemon.cc
+++ b/daemon.cc
@@ -21,6 +21,8 @@
#include <base/logging.h>
#include <base/run_loop.h>
+#include <dhcp_client/dbus/dbus_control.h>
+
namespace dhcp_client {
Daemon::Daemon(const base::Closure& startup_callback)
@@ -33,6 +35,9 @@
return return_code;
}
+ control_interface_.reset(new DBusControl());
+ control_interface_->Init();
+
startup_callback_.Run();
return EX_OK;
diff --git a/daemon.h b/daemon.h
index a4ed039..675b18c 100644
--- a/daemon.h
+++ b/daemon.h
@@ -20,6 +20,8 @@
#include <base/callback_forward.h>
#include <brillo/daemons/dbus_daemon.h>
+#include "dhcp_client/control_interface.h"
+
namespace dhcp_client {
class Daemon : public brillo::Daemon {
@@ -34,6 +36,8 @@
private:
base::Closure startup_callback_;
+ std::unique_ptr<ControlInterface> control_interface_;
+
DISALLOW_COPY_AND_ASSIGN(Daemon);
};
diff --git a/dbus/dbus_control.cc b/dbus/dbus_control.cc
new file mode 100644
index 0000000..0697f58
--- /dev/null
+++ b/dbus/dbus_control.cc
@@ -0,0 +1,95 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "dhcp_client/dbus/dbus_control.h"
+
+#include "dhcp_client/dbus/manager_dbus_adaptor.h"
+#include "dhcp_client/dbus/service_dbus_adaptor.h"
+#include "dhcp_client/manager.h"
+#include "dhcp_client/service.h"
+
+
+using brillo::dbus_utils::AsyncEventSequencer;
+using brillo::dbus_utils::ExportedObjectManager;
+
+namespace dhcp_client {
+
+namespace {
+const char kServiceName[] = "org.chromium.dhcp_client";
+const char kServicePath[] = "/org/chromium/dhcp_client";
+} // namespace
+
+DBusControl::DBusControl() {}
+
+DBusControl::~DBusControl() {}
+
+void DBusControl::Init() {
+ // Setup bus connection.
+ dbus::Bus::Options options;
+ options.bus_type = dbus::Bus::SYSTEM;
+ bus_ = new dbus::Bus(options);
+ CHECK(bus_->Connect());
+
+ // Create and register ObjectManager.
+ scoped_refptr<AsyncEventSequencer> sequencer(new AsyncEventSequencer());
+ object_manager_.reset(
+ new ExportedObjectManager(bus_, dbus::ObjectPath(kServicePath)));
+ object_manager_->RegisterAsync(
+ sequencer->GetHandler("ObjectManager.RegisterAsync() failed.", true));
+
+ // Create and register Manager.
+ manager_.reset(new Manager(this));
+ manager_->RegisterAsync(
+ sequencer->GetHandler("Manager.RegisterAsync() failed.", true));
+
+ // Take over the service ownership once the objects registration is completed.
+ sequencer->OnAllTasksCompletedCall({
+ base::Bind(&DBusControl::OnObjectRegistrationCompleted,
+ base::Unretained(this))
+ });
+}
+
+void DBusControl::Shutdown() {
+ manager_.reset();
+ object_manager_.reset();
+ if (bus_) {
+ bus_->ShutdownAndBlock();
+ }
+}
+
+void DBusControl::OnObjectRegistrationCompleted(bool registration_success) {
+ // Success should always be true since we've said that failures are fatal.
+ CHECK(registration_success) << "Init of one or more objects has failed.";
+ CHECK(bus_->RequestOwnershipAndBlock(kServiceName,
+ dbus::Bus::REQUIRE_PRIMARY))
+ << "Unable to take ownership of " << kServiceName;
+
+}
+
+std::unique_ptr<ManagerAdaptorInterface> DBusControl::CreateManagerAdaptor(
+ Manager* manager) {
+ return std::unique_ptr<ManagerAdaptorInterface>(
+ new ManagerDBusAdaptor(bus_, object_manager_.get(), manager));
+}
+
+std::unique_ptr<ServiceAdaptorInterface> DBusControl::CreateServiceAdaptor(
+ Service* service) {
+ return std::unique_ptr<ServiceAdaptorInterface>(
+ new ServiceDBusAdaptor(bus_, object_manager_.get(), service));
+}
+
+
+} // namespace dhcp_client
diff --git a/dbus/dbus_control.h b/dbus/dbus_control.h
new file mode 100644
index 0000000..e47a10f
--- /dev/null
+++ b/dbus/dbus_control.h
@@ -0,0 +1,62 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef DHCP_CLIENT_DBUS_DBUS_CONTROL_H_
+#define DHCP_CLIENT_DBUS_DBUS_CONTROL_H_
+
+#include <base/macros.h>
+#include <brillo/dbus/exported_object_manager.h>
+#include <dbus/bus.h>
+
+#include "dhcp_client/control_interface.h"
+#include "dhcp_client/manager.h"
+#include "dhcp_client/service.h"
+
+namespace dhcp_client {
+
+// D-Bus control interface for IPC through D-Bus.
+class DBusControl : public ControlInterface {
+ public:
+ DBusControl();
+ ~DBusControl() override;
+
+ // Inheritted from ControlInterface.
+ void Init() override;
+ void Shutdown() override;
+ std::unique_ptr<ManagerAdaptorInterface> CreateManagerAdaptor(
+ Manager* manager) override;
+ std::unique_ptr<ServiceAdaptorInterface> CreateServiceAdaptor(
+ Service* service) override;
+
+ private:
+ // Invoked when D-Bus objects for both ObjectManager and Manager
+ // are registered to the bus.
+ void OnObjectRegistrationCompleted(bool registration_success);
+
+ // NOTE: No dedicated bus is needed for the proxies, since the proxies
+ // being created here doesn't listen for any broadcast signals.
+ // Use a dedicated bus for the proxies if this condition is not true
+ // anymore.
+ scoped_refptr<dbus::Bus> bus_;
+ std::unique_ptr<brillo::dbus_utils::ExportedObjectManager> object_manager_;
+ std::unique_ptr<Manager> manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(DBusControl);
+};
+
+} // namespace dhcp_client
+
+#endif // DHCP_CLIENT_DBUS_DBUS_CONTROL_H_
diff --git a/dbus/manager_dbus_adaptor.cc b/dbus/manager_dbus_adaptor.cc
new file mode 100644
index 0000000..f33fa38
--- /dev/null
+++ b/dbus/manager_dbus_adaptor.cc
@@ -0,0 +1,100 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+
+#include "dhcp_client/dbus/manager_dbus_adaptor.h"
+
+#include <string>
+
+#include "dhcp_client/manager.h"
+
+using brillo::dbus_utils::ExportedObjectManager;
+using org::chromium::dhcp_client::ManagerAdaptor;
+using std::string;
+
+namespace dhcp_client {
+
+ManagerDBusAdaptor::ManagerDBusAdaptor(
+ const scoped_refptr<dbus::Bus>& bus,
+ ExportedObjectManager* object_manager,
+ Manager* manager)
+ : adaptor_(this),
+ dbus_object_(object_manager, bus, ManagerAdaptor::GetObjectPath()),
+ bus_(bus),
+ manager_(manager) {}
+
+ManagerDBusAdaptor::~ManagerDBusAdaptor() {}
+
+void ManagerDBusAdaptor::RegisterAsync(
+ const base::Callback<void(bool)>& completion_callback) {
+ adaptor_.RegisterWithDBusObject(&dbus_object_);
+ dbus_object_.RegisterAsync(completion_callback);
+}
+
+bool ManagerDBusAdaptor::StartService(brillo::ErrorPtr* dbus_error,
+ dbus::Message* message,
+ const brillo::VariantDictionary& configs,
+ dbus::ObjectPath* out_service) {
+ auto service = manager_->StartService(configs);
+ if (!service) {
+ // TODO(nywang): set dbus_error.
+ return false;
+ }
+
+ *out_service = service->adaptor()->GetRpcObjectIdentifier();
+
+ // Setup monitoring for the service's remote owner.
+ service_owner_watchers_[*out_service] =
+ ServiceOwnerWatcherContext(
+ service,
+ std::unique_ptr<DBusServiceWatcher>(
+ new DBusServiceWatcher(
+ bus_,
+ message->GetSender(),
+ base::Bind(&ManagerDBusAdaptor::OnServiceOwnerVanished,
+ base::Unretained(this),
+ *out_service))));
+ return true;
+}
+
+bool ManagerDBusAdaptor::StopService(brillo::ErrorPtr* dbus_error,
+ dbus::Message* message,
+ const dbus::ObjectPath& in_service) {
+ auto watcher_context = service_owner_watchers_.find(in_service);
+ if (watcher_context == service_owner_watchers_.end()) {
+ // TODO(nywang): set dbus_error.
+ return false;
+ }
+
+ manager_->StopService(watcher_context->second.service);
+ service_owner_watchers_.erase(watcher_context);
+ return true;
+}
+
+void ManagerDBusAdaptor::OnServiceOwnerVanished(
+ const dbus::ObjectPath& service_path) {
+ LOG(INFO) << "Owner for service " << service_path.value() << " vanished";
+ // Remove service watcher.
+ auto watcher_context = service_owner_watchers_.find(service_path);
+ CHECK(watcher_context != service_owner_watchers_.end())
+ << "Owner vanished without watcher setup.";
+
+ // Tell Manager to remove this service.
+ manager_->StopService(watcher_context->second.service);
+ service_owner_watchers_.erase(watcher_context);
+}
+
+} // namespace dhcp_client
diff --git a/dbus/manager_dbus_adaptor.h b/dbus/manager_dbus_adaptor.h
new file mode 100644
index 0000000..536e9f5
--- /dev/null
+++ b/dbus/manager_dbus_adaptor.h
@@ -0,0 +1,83 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef DHCP_CLIENT_DBUS_MANAGER_DBUS_ADAPTOR_H_
+#define DHCP_CLIENT_DBUS_MANAGER_DBUS_ADAPTOR_H_
+
+#include <map>
+
+#include <base/macros.h>
+#include <brillo/dbus/dbus_service_watcher.h>
+#include <dbus_bindings/org.chromium.dhcp_client.Manager.h>
+
+#include "dhcp_client/manager_adaptor_interface.h"
+
+namespace dhcp_client {
+
+class Manager;
+class Service;
+
+class ManagerDBusAdaptor : public org::chromium::dhcp_client::ManagerInterface,
+ public ManagerAdaptorInterface {
+ public:
+ ManagerDBusAdaptor(const scoped_refptr<dbus::Bus>& bus,
+ brillo::dbus_utils::ExportedObjectManager* object_manager,
+ Manager* manager);
+ ~ManagerDBusAdaptor() override;
+
+ // Implementation of org::chromium::dhcp_client::ManagerInterface.
+ bool StartService(brillo::ErrorPtr* dbus_error,
+ dbus::Message* message,
+ const brillo::VariantDictionary& configs,
+ dbus::ObjectPath* out_service) override;
+ bool StopService(brillo::ErrorPtr* dbus_error,
+ dbus::Message* message,
+ const dbus::ObjectPath& in_service) override;
+
+ // Implementation of ManagerAdaptorInterface.
+ void RegisterAsync(
+ const base::Callback<void(bool)>& completion_callback) override;
+
+ private:
+ using DBusServiceWatcher = brillo::dbus_utils::DBusServiceWatcher;
+ // Context for service owner watcher.
+ struct ServiceOwnerWatcherContext {
+ ServiceOwnerWatcherContext() {}
+ ServiceOwnerWatcherContext(const scoped_refptr<Service>& in_service,
+ std::unique_ptr<DBusServiceWatcher> in_watcher)
+ : service(in_service),
+ watcher(std::move(in_watcher)) {}
+ scoped_refptr<Service> service;
+ std::unique_ptr<DBusServiceWatcher> watcher;
+ };
+
+ // Invoked when the owner of a Service vanished.
+ void OnServiceOwnerVanished(const dbus::ObjectPath& service_path);
+
+ org::chromium::dhcp_client::ManagerAdaptor adaptor_;
+ brillo::dbus_utils::DBusObject dbus_object_;
+ scoped_refptr<dbus::Bus> bus_;
+ Manager* manager_;
+ // Map of service path to owner monitor context.
+ std::map<dbus::ObjectPath, ServiceOwnerWatcherContext>
+ service_owner_watchers_;
+
+ DISALLOW_COPY_AND_ASSIGN(ManagerDBusAdaptor);
+};
+
+} // namespace dhcp_client
+
+#endif // DHCP_CLIENT_DBUS_MANAGER_DBUS_ADAPTOR_H_
diff --git a/dbus/service_dbus_adaptor.cc b/dbus/service_dbus_adaptor.cc
new file mode 100644
index 0000000..57f6592
--- /dev/null
+++ b/dbus/service_dbus_adaptor.cc
@@ -0,0 +1,57 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "dhcp_client/dbus/service_dbus_adaptor.h"
+
+#include <string>
+
+#include <base/bind.h>
+#include <base/strings/stringprintf.h>
+#include <dbus_bindings/org.chromium.dhcp_client.Manager.h>
+
+#include "dhcp_client/service.h"
+
+using brillo::dbus_utils::ExportedObjectManager;
+using brillo::dbus_utils::DBusMethodResponse;
+using brillo::dbus_utils::DBusObject;
+using org::chromium::dhcp_client::ManagerAdaptor;
+using std::string;
+
+namespace dhcp_client {
+
+ServiceDBusAdaptor::ServiceDBusAdaptor(
+ const scoped_refptr<dbus::Bus>& bus,
+ ExportedObjectManager* object_manager,
+ Service* service)
+ : adaptor_(this),
+ object_path_(
+ base::StringPrintf("%s/services/%d",
+ ManagerAdaptor::GetObjectPath().value().c_str(),
+ service->identifier())),
+ dbus_object_(object_manager, bus, object_path_),
+ service_(service) {
+ // Register D-Bus object.
+ adaptor_.RegisterWithDBusObject(&dbus_object_);
+ dbus_object_.RegisterAndBlock();
+}
+
+ServiceDBusAdaptor::~ServiceDBusAdaptor() {}
+
+RPCObjectIdentifier ServiceDBusAdaptor::GetRpcObjectIdentifier() {
+ return object_path_;
+}
+
+} // namespace dhcp_client
diff --git a/dbus/service_dbus_adaptor.h b/dbus/service_dbus_adaptor.h
new file mode 100644
index 0000000..80e555b
--- /dev/null
+++ b/dbus/service_dbus_adaptor.h
@@ -0,0 +1,53 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef DHCP_CLIENT_DBUS_SERVICE_DBUS_ADAPTOR_H_
+#define DHCP_CLIENT_DBUS_SERVICE_DBUS_ADAPTOR_H_
+
+#include <base/macros.h>
+
+#include <dbus_bindings/org.chromium.dhcp_client.Service.h>
+
+#include "dhcp_client/service_adaptor_interface.h"
+
+namespace dhcp_client {
+
+class Service;
+
+class ServiceDBusAdaptor : public org::chromium::dhcp_client::ServiceInterface,
+ public ServiceAdaptorInterface {
+ public:
+ ServiceDBusAdaptor(const scoped_refptr<dbus::Bus>& bus,
+ brillo::dbus_utils::ExportedObjectManager* object_manager,
+ Service* service);
+ ~ServiceDBusAdaptor() override;
+
+ // Implementation of ServiceAdaptorInterface.
+ RPCObjectIdentifier GetRpcObjectIdentifier() override;
+ // TODO(nywang): implement signal 'Event'
+
+ private:
+ org::chromium::dhcp_client::ServiceAdaptor adaptor_;
+ dbus::ObjectPath object_path_;
+ brillo::dbus_utils::DBusObject dbus_object_;
+ Service* service_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceDBusAdaptor);
+};
+
+} // namespace dhcp_client
+
+#endif // DHCP_CLIENT_DBUS_SERVICE_DBUS_ADAPTOR_H_
diff --git a/dbus_bindings/dbus-service-config.json b/dbus_bindings/dbus-service-config.json
new file mode 100644
index 0000000..647c046
--- /dev/null
+++ b/dbus_bindings/dbus-service-config.json
@@ -0,0 +1,6 @@
+{
+ "service_name": "org.chromium.dhcp_client",
+ "object_manager": {
+ "object_path": "/org/chromium/dhcp_client"
+ }
+}
diff --git a/dbus_bindings/org.chromium.dhcp_client.Manager.dbus-xml b/dbus_bindings/org.chromium.dhcp_client.Manager.dbus-xml
new file mode 100644
index 0000000..292424a
--- /dev/null
+++ b/dbus_bindings/org.chromium.dhcp_client.Manager.dbus-xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/org/chromium/dhcp_client/Manager"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <interface name="org.chromium.dhcp_client.Manager">
+ <method name="StartService">
+ <arg name="args" type="a{sv}" direction="in"/>
+ <arg name="service" type="o" direction="out"/>
+ <annotation name="org.chromium.DBus.Method.IncludeDBusMessage"
+ value="true"/>
+ </method>
+ <method name="StopService">
+ <arg name="service" type="o" direction="in"/>
+ <annotation name="org.chromium.DBus.Method.IncludeDBusMessage"
+ value="true"/>
+ </method>
+ </interface>
+</node>
diff --git a/dbus_bindings/org.chromium.dhcp_client.Service.dbus-xml b/dbus_bindings/org.chromium.dhcp_client.Service.dbus-xml
new file mode 100644
index 0000000..e2d5101
--- /dev/null
+++ b/dbus_bindings/org.chromium.dhcp_client.Service.dbus-xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <interface name="org.chromium.dhcp_client.Service">
+ <signal name="Event">
+ <arg name = "configuration" type="a{sv}"/>
+ </signal>
+ </interface>
+</node>
diff --git a/dbus_permissions/org.chromium.dhcp_client.conf b/dbus_permissions/org.chromium.dhcp_client.conf
new file mode 100644
index 0000000..a4abf20
--- /dev/null
+++ b/dbus_permissions/org.chromium.dhcp_client.conf
@@ -0,0 +1,16 @@
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+ <policy user="root">
+ <allow own="org.chromium.dhcp_client"/>
+ <allow send_destination="org.chromium.dhcp_client"/>
+ </policy>
+
+ <policy user="dhcp">
+ <allow own="org.chromium.dhcp_client"/>
+ </policy>
+
+ <policy group="dhcp">
+ <allow send_destination="org.chromium.dhcp_client" />
+ </policy>
+</busconfig>
diff --git a/dhcp_client.gyp b/dhcp_client.gyp
index 709cc4d..8240ed2 100644
--- a/dhcp_client.gyp
+++ b/dhcp_client.gyp
@@ -40,9 +40,26 @@
},
'targets': [
+ {
+ 'target_name': 'dhcp_client-adaptors',
+ 'type': 'none',
+ 'variables': {
+ 'dbus_adaptors_out_dir': 'include/dbus_bindings',
+ 'dbus_xml_extension': 'dbus-xml',
+ },
+ 'sources': [
+ 'dbus_bindings/org.chromium.dhcp_client.Manager.dbus-xml',
+ 'dbus_bindings/org.chromium.dhcp_client.Service.dbus-xml',
+ ],
+ 'includes': ['../../../../platform2/common-mk/generate-dbus-adaptors.gypi'],
+ },
+
{
'target_name': 'libdhcp_client',
'type': 'static_library',
+ 'dependencies': [
+ 'dhcp_client-adaptors',
+ ],
'variables': {
'exported_deps': [
],
@@ -57,6 +74,9 @@
},
'sources': [
'daemon.cc',
+ 'dbus/dbus_control.cc',
+ 'dbus/manager_dbus_adaptor.cc',
+ 'dbus/service_dbus_adaptor.cc',
'device_info.cc',
'dhcp_message.cc',
'dhcp_options_parser.cc',
diff --git a/dhcpv4.cc b/dhcpv4.cc
index 6f4a21b..bf78157 100644
--- a/dhcpv4.cc
+++ b/dhcpv4.cc
@@ -117,7 +117,9 @@
}
DHCPV4::~DHCPV4() {
- Stop();
+ if (socket_ != kInvalidSocketDescriptor) {
+ Stop();
+ }
}
void DHCPV4::ResetStateVariables() {
@@ -242,6 +244,7 @@
}
if (socket_ != kInvalidSocketDescriptor) {
sockets_->Close(socket_);
+ socket_ = kInvalidSocketDescriptor;
}
}
@@ -515,11 +518,11 @@
message.SetServerIdentifier(server_identifier_);
ByteString packet;
if (!MakeRawPacket(message, &packet)) {
- LOG(ERROR) << "Failed to serialize a DHCP discover message";
+ LOG(ERROR) << "Failed to serialize a DHCP release message";
return false;
}
if (!SendRawPacket(packet)) {
- LOG(ERROR) << "Failed to send a DHCP discover packet";
+ LOG(ERROR) << "Failed to send a DHCP release packet";
return false;
}
// Set state variables upon success.
diff --git a/manager.cc b/manager.cc
index e0844e1..33a65f5 100644
--- a/manager.cc
+++ b/manager.cc
@@ -18,16 +18,24 @@
#include "dhcp_client/service.h"
#include "dhcp_client/message_loop_event_dispatcher.h"
+#include "dhcp_client/control_interface.h"
namespace dhcp_client {
-Manager::Manager()
- : service_identifier_(0),
- event_dispatcher_(new MessageLoopEventDispatcher()) {
+Manager::Manager(ControlInterface* control_interface)
+ : control_interface_(control_interface),
+ service_identifier_(0),
+ event_dispatcher_(new MessageLoopEventDispatcher()),
+ adaptor_(control_interface->CreateManagerAdaptor(this)) {
}
Manager::~Manager() {}
+void Manager::RegisterAsync(
+ const base::Callback<void(bool)>& completion_callback) {
+ adaptor_->RegisterAsync(completion_callback);
+}
+
scoped_refptr<Service> Manager::StartService(
const brillo::VariantDictionary& configs) {
scoped_refptr<Service> service = new Service(this,
diff --git a/manager.h b/manager.h
index 88c2428..896f9d2 100644
--- a/manager.h
+++ b/manager.h
@@ -23,24 +23,33 @@
#include <brillo/variant_dictionary.h>
#include "dhcp_client/event_dispatcher_interface.h"
+#include "dhcp_client/manager_adaptor_interface.h"
#include "dhcp_client/service.h"
namespace dhcp_client {
+class ControlInterface;
+
class Manager {
public:
- Manager();
+ // Register this object to the RPC interface asynchronously.
+ void RegisterAsync(const base::Callback<void(bool)>&
+ completion_callback);
+ explicit Manager(ControlInterface* control_interface);
virtual ~Manager();
scoped_refptr<Service> StartService(const brillo::VariantDictionary& configs);
bool StopService(const scoped_refptr<Service>& service);
+ ControlInterface* control_interface() const { return control_interface_; }
private:
+ ControlInterface* control_interface_;
int service_identifier_;
std::unique_ptr<EventDispatcherInterface> event_dispatcher_;
std::vector<scoped_refptr<Service>> services_;
+ std::unique_ptr<ManagerAdaptorInterface> adaptor_;
DISALLOW_COPY_AND_ASSIGN(Manager);
};
diff --git a/manager_adaptor_interface.h b/manager_adaptor_interface.h
new file mode 100644
index 0000000..c9c5745
--- /dev/null
+++ b/manager_adaptor_interface.h
@@ -0,0 +1,34 @@
+//
+// Copyright 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef DHCP_CLIENT_MANAGER_ADAPTOR_INTERFACE_H_
+#define DHCP_CLIENT_MANAGER_ADAPTOR_INTERFACE_H_
+
+#include <base/callback.h>
+
+namespace dhcp_client {
+
+class ManagerAdaptorInterface {
+ public:
+ virtual ~ManagerAdaptorInterface() {}
+
+ virtual void RegisterAsync(
+ const base::Callback<void(bool)>& completion_callback) = 0;
+};
+
+} // namespace dhcp_client
+
+#endif // DHCP_CLIENT_MANAGER_ADAPTOR_INTERFACE_H_
diff --git a/rpc_interface.h b/rpc_interface.h
new file mode 100644
index 0000000..70c3021
--- /dev/null
+++ b/rpc_interface.h
@@ -0,0 +1,29 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef DHCP_CLIENT_RPC_INTERFACE_H_
+#define DHCP_CLIENT_RPC_INTERFACE_H_
+
+// TODO(nywang): put this under a compiler flag (e.g. __DBUS__).
+#include <dbus/object_path.h>
+
+namespace dhcp_client {
+
+// TODO(nywang): put this under a compiler flag (e.g. __DBUS__).
+typedef dbus::ObjectPath RPCObjectIdentifier;
+
+} // namespace dhcp_client
+
+#endif // DHCP_CLIENT_RPC_INTERFACE_H_
diff --git a/service.cc b/service.cc
index 77a412e..562980c 100644
--- a/service.cc
+++ b/service.cc
@@ -18,7 +18,9 @@
#include <string>
+#include "dhcp_client/control_interface.h"
#include "dhcp_client/device_info.h"
+#include "dhcp_client/manager.h"
using std::string;
@@ -41,6 +43,7 @@
const brillo::VariantDictionary& configs)
: manager_(manager),
identifier_(service_identifier),
+ adaptor_(manager->control_interface()->CreateServiceAdaptor(this)),
event_dispatcher_(event_dispatcher),
type_(DHCP::SERVICE_TYPE_IPV4),
request_hostname_(false),
@@ -49,19 +52,22 @@
request_na_(false),
request_pd_(false) {
ParseConfigs(configs);
+ event_dispatcher_->PostTask(Bind(&Service::Start, Unretained(this)));
}
Service::~Service() {
- Stop();
+ if (state_machine_ipv4_) {
+ Stop();
+ }
}
-bool Service::Start() {
+void Service::Start() {
if (!DeviceInfo::GetInstance()->GetDeviceInfo(interface_name_,
&hardware_address_,
&interface_index_)) {
LOG(ERROR) << "Unable to get interface information for: "
<< interface_name_;
- return false;
+ return;
}
if (type_ == DHCP::SERVICE_TYPE_IPV4 ||
@@ -83,7 +89,7 @@
state_machine_ipv4_->Start();
}
// TODO(nywang): Start DHCP state machine for IPV6.
- return true;
+ return;
}
void Service::Stop() {
diff --git a/service.h b/service.h
index b0044aa..43e6eee 100644
--- a/service.h
+++ b/service.h
@@ -26,6 +26,7 @@
#include "dhcp_client/dhcp.h"
#include "dhcp_client/dhcpv4.h"
#include "dhcp_client/event_dispatcher_interface.h"
+#include "dhcp_client/service_adaptor_interface.h"
#include "shill/net/byte_string.h"
namespace dhcp_client {
@@ -40,13 +41,16 @@
const brillo::VariantDictionary& configs);
virtual ~Service();
- bool Start();
+ void Start();
void Stop();
+ ServiceAdaptorInterface* adaptor() const { return adaptor_.get(); }
+ int identifier() { return identifier_; }
private:
Manager* manager_;
// Indentifier number of this service.
int identifier_;
+ std::unique_ptr<ServiceAdaptorInterface> adaptor_;
EventDispatcherInterface* event_dispatcher_;
// Interface parameters.
std::string interface_name_;
diff --git a/service_adaptor_interface.h b/service_adaptor_interface.h
new file mode 100644
index 0000000..f720541
--- /dev/null
+++ b/service_adaptor_interface.h
@@ -0,0 +1,36 @@
+//
+// Copyright 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef DHCP_CLIENT_SERVICE_ADAPTOR_INTERFACE_H_
+#define DHCP_CLIENT_SERVICE_ADAPTOR_INTERFACE_H_
+
+#include <string>
+
+#include "dhcp_client/rpc_interface.h"
+
+namespace dhcp_client {
+
+class Config;
+
+class ServiceAdaptorInterface {
+ public:
+ virtual ~ServiceAdaptorInterface() {}
+ virtual RPCObjectIdentifier GetRpcObjectIdentifier() = 0;
+};
+
+} // namespace dhcp_client
+
+#endif // DHCP_CLIENT_SERVICE_ADAPTOR_INTERFACE_H_