cashew: Add ipconfig dbus object

Add ipconfig dbus object

BUG=chromium-os:27904
TEST=fetch usage information while attached to Ethernet

Change-Id: I112f6c1e07657215170c925d06a6bde245186d47
Reviewed-on: https://gerrit.chromium.org/gerrit/18802
Reviewed-by: Nathan J. Williams <njw@chromium.org>
Commit-Ready: <jglasgow@google.com>
Tested-by: <jglasgow@google.com>
diff --git a/src/Makefile.am b/src/Makefile.am
index e0ad1e0..120744d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -34,6 +34,10 @@
   device_impl.h \
   device_impl.cc \
   http_fetcher.h \
+  ipconfig.h \
+  ipconfig.cc \
+  ipconfig_impl.h \
+  ipconfig_impl.cc \
   libcurl_http_fetcher.h \
   libcurl_http_fetcher.cc \
   metrics_manager.h \
diff --git a/src/ipconfig.cc b/src/ipconfig.cc
new file mode 100644
index 0000000..9eb438e
--- /dev/null
+++ b/src/ipconfig.cc
@@ -0,0 +1,19 @@
+// Copyright (c) 2012 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 "src/ipconfig.h"
+
+#include <glog/logging.h>
+
+#include "src/ipconfig_impl.h"
+
+namespace cashew {
+
+// static
+Ipconfig* Ipconfig::NewIpconfig(DBus::Connection& connection,  // NOLINT
+                                const DBus::Path& path) {
+  return new(std::nothrow) IpconfigImpl(connection, path);
+}
+
+}  // namespace cashew
diff --git a/src/ipconfig.h b/src/ipconfig.h
new file mode 100644
index 0000000..786a088
--- /dev/null
+++ b/src/ipconfig.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2012 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 SRC_IPCONFIG_H_
+#define SRC_IPCONFIG_H_
+
+#include <string>
+#include <vector>
+
+#include <base/basictypes.h>  // NOLINT
+#include <dbus-c++/dbus.h>  // NOLINT
+
+namespace cashew {
+
+class Device;
+
+// Ipconfig interface
+// represents a Flimflam ipconfig
+class Ipconfig {
+  public:
+    Ipconfig() {}
+    virtual ~Ipconfig() {}
+
+    // get D-Bus path for this ipconfig
+    virtual const DBus::Path& GetPath() const = 0;
+
+    // get the list of nameservers for ths ipconfig
+    // returns empty list if we don't know
+    virtual const std::vector<std::string>& GetNameServers() = 0;
+
+    // factory
+    static Ipconfig* NewIpconfig(DBus::Connection& connection,  // NOLINT
+                                 const DBus::Path& path);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(Ipconfig);
+};
+
+}  // namespace cashew
+
+#endif  // SRC_IPCONFIG_H_
diff --git a/src/ipconfig_impl.cc b/src/ipconfig_impl.cc
new file mode 100644
index 0000000..6be6265
--- /dev/null
+++ b/src/ipconfig_impl.cc
@@ -0,0 +1,74 @@
+// 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 "src/ipconfig_impl.h"
+
+#include <glog/logging.h>
+
+#include "src/device.h"
+#include "src/service.h"
+
+using std::vector;
+
+namespace cashew {
+
+// Flimflam Ipconfig D-Bus identifiers
+static const char *kFlimflamIpconfigName = "org.chromium.flimflam";
+
+// Flimflam Ipconfig property names
+static const char *kFlimflamIpconfigNameServersProperty = "NameServers";
+
+IpconfigImpl::IpconfigImpl(DBus::Connection& connection,  // NOLINT
+                           const DBus::Path& path)
+    : DBus::ObjectProxy(connection, path, kFlimflamIpconfigName), path_(path) {
+}
+
+IpconfigImpl::~IpconfigImpl() {
+}
+
+const DBus::Path& IpconfigImpl::GetPath() const {
+  return path_;
+}
+
+const vector<std::string>& IpconfigImpl::GetNameServers() {
+  GetIpconfigProperties();
+  return nameservers_;
+}
+
+// Private methods
+
+bool IpconfigImpl::GetIpconfigProperties() {
+  LOG(INFO) << path_ << ": GetIpconfigProperties";
+  PropertyMap properties;
+  // dbus-c++ throws exceptions
+  // invoke the "Existing Non-conformant Code" clause of the style guide and
+  // isolate the rest of the system from this
+  try {
+    // TODO(jglasgow): make this call asynchronous
+    properties = GetProperties();
+  } catch (DBus::Error& error) {  // NOLINT
+    LOG(WARNING) << path_
+        << ": GetIpconfigProperties: GetProperties() -> Exception: "
+        << error.name() << ": " << error.message();
+    return false;
+  } catch (...) {  // NOLINT
+    LOG(WARNING) << path_
+        << ": GetIpconfigProperties: GetProperties() -> Exception";
+    return false;
+  }
+  LOG(INFO) << "Received " << properties.size() << " properties";
+
+  // grab the properties in which we're interested
+  PropertyMap::const_iterator it(
+      properties.find(kFlimflamIpconfigNameServersProperty));
+  if (it != properties.end()) {
+    const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
+    nameservers_ = value.operator vector<std::string>();
+  } else {
+    LOG(WARNING) << path_ << ": GetIpconfigProperties: no NameServers property";
+  }
+  return true;
+}
+
+}  // namespace cashew
diff --git a/src/ipconfig_impl.h b/src/ipconfig_impl.h
new file mode 100644
index 0000000..1fc64fd
--- /dev/null
+++ b/src/ipconfig_impl.h
@@ -0,0 +1,55 @@
+// 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 SRC_IPCONFIG_IMPL_H_
+#define SRC_IPCONFIG_IMPL_H_
+
+#include <glib.h>
+
+#include <string>
+#include <vector>
+
+#include <base/basictypes.h>  // NOLINT
+#include <dbus-c++/dbus.h>  // NOLINT
+
+#include "src/ipconfig.h"
+#include "src/flimflam_ipconfig_client_glue.h"
+#include "src/property_changed_handler.h"
+
+namespace cashew {
+
+// represents an ipconfig and provides access to ipconfig properties
+// flimflam does not send change signals for ipconfig objects so
+// nothing is cached
+class IpconfigImpl : public Ipconfig,
+                     public org::chromium::flimflam::IPConfig_proxy,
+                     public DBus::IntrospectableProxy,
+                     public DBus::ObjectProxy {
+  public:
+    IpconfigImpl(DBus::Connection& connection,  // NOLINT
+                 const DBus::Path& path);
+    virtual ~IpconfigImpl();
+
+    // Ipconfig methods
+    virtual const DBus::Path& GetPath() const;
+    virtual const std::vector<std::string>& GetNameServers();
+
+  private:
+    // D-Bus path for Flimflam ipconfig that we represent
+    // this is our unique identifier
+    const DBus::Path path_;
+
+    // name servers
+    std::vector<std::string> nameservers_;
+
+    // get ipconfig properties from Flimflam
+    // returns true on success and false on failure
+    bool GetIpconfigProperties();
+
+    DISALLOW_COPY_AND_ASSIGN(IpconfigImpl);
+};
+
+}  // namespace cashew
+
+#endif  // SRC_IPCONFIG_IMPL_H_