shill -- connect dhcp config to proxies and provider.

In addition, spawn dhcpcd on request.

Cleanup the Makefile a bit. Don't do lazy initialization of dbus_control so that
the connection can be passed to DHCPProvider.

BUG=chromium-os:16013
TEST=modified device_info to request a DHCPConfig for a DeviceStub.

Change-Id: Ib3b032b25bd5b071635816635bf6066cc3b386d5
Reviewed-on: http://gerrit.chromium.org/gerrit/2024
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Chris Masone <cmasone@chromium.org>
diff --git a/dhcpcd_proxy.cc b/dhcpcd_proxy.cc
index 3ff6983..9f577c5 100644
--- a/dhcpcd_proxy.cc
+++ b/dhcpcd_proxy.cc
@@ -6,14 +6,20 @@
 
 #include <base/logging.h>
 
+#include "shill/dhcp_provider.h"
+
+using std::string;
+
 namespace shill {
 
 const char DHCPCDProxy::kDBusInterfaceName[] = "org.chromium.dhcpcd";
 const char DHCPCDProxy::kDBusPath[] = "/org/chromium/dhcpcd";
 
-DHCPCDListener::DHCPCDListener(DBus::Connection *connection)
+DHCPCDListener::DHCPCDListener(DHCPProvider *provider,
+                               DBus::Connection *connection)
     : DBus::InterfaceProxy(DHCPCDProxy::kDBusInterfaceName),
-      DBus::ObjectProxy(*connection, DHCPCDProxy::kDBusPath) {
+      DBus::ObjectProxy(*connection, DHCPCDProxy::kDBusPath),
+      provider_(provider) {
   VLOG(2) << __func__;
   connect_signal(DHCPCDListener, Event, EventSignal);
   connect_signal(DHCPCDListener, StatusChanged, StatusChangedSignal);
@@ -25,7 +31,15 @@
   unsigned int pid;
   ri >> pid;
   VLOG(2) << "sender(" << signal.sender() << ") pid(" << pid << ")";
-  // TODO(petkov): Dispatch the signal to the appropriate DHCPCDProxy.
+
+  DHCPConfigRefPtr config = provider_->GetConfig(pid);
+  if (!config.get()) {
+    LOG(ERROR) << "Unknown DHCP client PID " << pid;
+    return;
+  }
+  config->InitProxy(&conn(), signal.sender());
+  // TODO(petkov): Process and dispatch the signal to the appropriate DHCP
+  // configuration.
 }
 
 void DHCPCDListener::StatusChangedSignal(const DBus::SignalMessage &signal) {
@@ -34,15 +48,21 @@
   unsigned int pid;
   ri >> pid;
   VLOG(2) << "sender(" << signal.sender() << ") pid(" << pid << ")";
-  // TODO(petkov): Dispatch the signal to the appropriate DHCPCDProxy.
+
+  // Accept StatusChanged signals just to get the sender address and create an
+  // appropriate proxy for the PID/sender pair.
+  DHCPConfigRefPtr config = provider_->GetConfig(pid);
+  if (!config.get()) {
+    LOG(ERROR) << "Unknown DHCP client PID " << pid;
+    return;
+  }
+  config->InitProxy(&conn(), signal.sender());
 }
 
-DHCPCDProxy::DHCPCDProxy(unsigned int pid,
-                         DBus::Connection *connection,
+DHCPCDProxy::DHCPCDProxy(DBus::Connection *connection,
                          const char *service)
-    : DBus::ObjectProxy(*connection, kDBusPath, service),
-      pid_(pid) {
-  VLOG(2) << "DHCPCDListener(pid=" << pid_ << " service=" << service << ").";
+    : DBus::ObjectProxy(*connection, kDBusPath, service) {
+  VLOG(2) << "DHCPCDProxy(service=" << service << ").";
 
   // Don't catch signals directly in this proxy because they will be dispatched
   // to us by the DHCPCD listener.
@@ -50,18 +70,20 @@
   _signals.erase("StatusChanged");
 }
 
+void DHCPCDProxy::DoRebind(const string &interface) {
+  Rebind(interface);
+}
+
 void DHCPCDProxy::Event(
     const uint32_t& pid,
     const std::string& reason,
     const std::map< std::string, DBus::Variant >& configuration) {
-  VLOG(2) << "Event(pid=" << pid << " reason=\"" << reason << "\")";
-  CHECK_EQ(pid, pid_);
+  NOTREACHED();
 }
 
 void DHCPCDProxy::StatusChanged(const uint32_t& pid,
                                 const std::string& status) {
-  VLOG(2) << "StatusChanged(pid=" << pid << " status=\"" << status << "\")";
-  CHECK_EQ(pid, pid_);
+  NOTREACHED();
 }
 
 }  // namespace shill