Update interface implementations to reflect changes to libweave

Pulling current version of libweave and making necessary changes to
weaved implementation of libweave's interfaces

Change-Id: I31d5d00ce1c7d2338257d62ec2dd510608ff71af
diff --git a/buffet/avahi_mdns_client.h b/buffet/avahi_mdns_client.h
index 2488dd4..681bd3b 100644
--- a/buffet/avahi_mdns_client.h
+++ b/buffet/avahi_mdns_client.h
@@ -22,7 +22,6 @@
 
 #include <base/memory/weak_ptr.h>
 #include <dbus/bus.h>
-#include <weave/dns_service_discovery_provider.h>
 
 #include "buffet/mdns_client.h"
 
@@ -34,7 +33,7 @@
   explicit AvahiMdnsClient(const scoped_refptr<dbus::Bus>& bus);
   ~AvahiMdnsClient() override;
 
-  // weave::DnsServiceDiscoveryProvider implementation.
+  // weave::provider::DnsServiceDiscovery implementation.
   void PublishService(const std::string& service_type, uint16_t port,
                       const std::vector<std::string>& txt) override;
   void StopPublishing(const std::string& service_type) override;
diff --git a/buffet/bluetooth_client.h b/buffet/bluetooth_client.h
index 3c2b666..52e32c8 100644
--- a/buffet/bluetooth_client.h
+++ b/buffet/bluetooth_client.h
@@ -20,11 +20,11 @@
 #include <memory>
 
 #include <base/macros.h>
-#include <weave/bluetooth.h>
+#include <weave/provider/bluetooth.h>
 
 namespace buffet {
 
-class BluetoothClient : public weave::Bluetooth {
+class BluetoothClient : public weave::provider::Bluetooth {
  public:
   BluetoothClient() {}
   ~BluetoothClient() override = default;
diff --git a/buffet/brillo_network_client.cc b/buffet/brillo_network_client.cc
index c467418..6f4a4dd 100644
--- a/buffet/brillo_network_client.cc
+++ b/buffet/brillo_network_client.cc
@@ -18,6 +18,8 @@
 
 #include <base/message_loop/message_loop.h>
 
+using weave::provider::Network;
+
 namespace buffet {
 
 namespace {
@@ -29,7 +31,7 @@
 
 BrilloNetworkClient::BrilloNetworkClient(
     const std::set<std::string>& device_whitelist)
-    : NetworkClient{device_whitelist}, state_(weave::NetworkState::kOffline) {
+    : NetworkClient{device_whitelist} {
   UpdateConnectionState();
 }
 
@@ -55,7 +57,7 @@
   }
 
   connection_success_closure_ = on_success;
-  state_ = weave::NetworkState::kConnecting;
+  connectivity_state_ = State::kConnecting;
 
   connection_timeout_closure_.Reset(
       base::Bind(&BrilloNetworkClient::OnConnectionTimeout,
@@ -68,13 +70,13 @@
   ScheduleNextStatePoll();
 }
 
-weave::NetworkState BrilloNetworkClient::GetConnectionState() const {
-  return state_;
+Network::State BrilloNetworkClient::GetConnectionState() const {
+  return connectivity_state_;
 }
 
 void BrilloNetworkClient::StartAccessPoint(const std::string& ssid) {
   connectivity_client_.EnableAccessPoint(ssid);
-  state_ = weave::NetworkState::kOffline;
+  connectivity_state_ = State::kOffline;
 }
 
 void BrilloNetworkClient::StopAccessPoint() {
@@ -82,7 +84,7 @@
 }
 
 void BrilloNetworkClient::OnConnectionTimeout() {
-  state_ = weave::NetworkState::kFailure;
+  connectivity_state_ = State::kFailure;
 }
 
 void BrilloNetworkClient::ScheduleNextStatePoll() {
@@ -90,7 +92,7 @@
       base::Bind(&BrilloNetworkClient::UpdateConnectionState,
                  base::Unretained(this)));
   int poll_period_seconds;
-  if (state_ == weave::NetworkState::kConnecting) {
+  if (connectivity_state_ == State::kConnecting) {
     poll_period_seconds = kConnectionActivePollSeconds;
   } else {
     poll_period_seconds = kConnectionInactivePollSeconds;
@@ -102,15 +104,15 @@
 }
 
 void BrilloNetworkClient::UpdateConnectionState() {
-  bool was_connected = state_ == weave::NetworkState::kConnected;
+  bool was_connected = connectivity_state_ == State::kConnected;
   bool is_connected = connectivity_client_.IsConnected();
 
   if (is_connected) {
-    if (state_ == weave::NetworkState::kConnecting)
+    if (connectivity_state_ == State::kConnecting)
       connection_success_closure_.Run();
-    state_ = weave::NetworkState::kConnected;
-  } else if (state_ == weave::NetworkState::kConnected) {
-    state_ = weave::NetworkState::kOffline;
+    connectivity_state_ = State::kConnected;
+  } else if (connectivity_state_ == State::kConnected) {
+    connectivity_state_ = State::kOffline;
   }
   if (is_connected != was_connected) {
     for (const auto& listener : connection_listeners_) {
diff --git a/buffet/brillo_network_client.h b/buffet/brillo_network_client.h
index f05bd97..f127a7e 100644
--- a/buffet/brillo_network_client.h
+++ b/buffet/brillo_network_client.h
@@ -21,7 +21,6 @@
 #include <vector>
 
 #include <base/cancelable_callback.h>
-#include <weave/network_provider.h>
 
 #include "connectivity_client.h"
 
@@ -42,7 +41,7 @@
       const std::string& passphrase,
       const weave::SuccessCallback& on_success,
       const base::Callback<void(const weave::Error*)>& on_error) override;
-  weave::NetworkState GetConnectionState() const override;
+  State GetConnectionState() const override;
   void StartAccessPoint(const std::string& ssid) override;
   void StopAccessPoint() override;
 
@@ -62,7 +61,7 @@
   base::CancelableClosure connection_timeout_closure_;
   base::CancelableClosure periodic_connection_state_closure_;
   base::Closure connection_success_closure_;
-  weave::NetworkState state_;
+  State connectivity_state_{State::kOffline};
   bool is_connected_;
 
   DISALLOW_COPY_AND_ASSIGN(BrilloNetworkClient);
diff --git a/buffet/buffet_config.h b/buffet/buffet_config.h
index e5b4e67..b83374d 100644
--- a/buffet/buffet_config.h
+++ b/buffet/buffet_config.h
@@ -13,7 +13,7 @@
 #include <base/callback.h>
 #include <base/files/file_path.h>
 #include <chromeos/key_value_store.h>
-#include <weave/config_store.h>
+#include <weave/provider/config_store.h>
 
 namespace buffet {
 
@@ -28,7 +28,7 @@
 };
 
 // Handles reading buffet config and state files.
-class BuffetConfig final : public weave::ConfigStore {
+class BuffetConfig final : public weave::provider::ConfigStore {
  public:
   using OnChangedCallback = base::Callback<void(const weave::Settings&)>;
   ~BuffetConfig() override = default;
diff --git a/buffet/http_transport_client.cc b/buffet/http_transport_client.cc
index 8d5c441..3996f5d 100644
--- a/buffet/http_transport_client.cc
+++ b/buffet/http_transport_client.cc
@@ -16,17 +16,19 @@
 
 namespace {
 
+using weave::provider::HttpClient;
+
 // The number of seconds each HTTP request will be allowed before timing out.
 const int kRequestTimeoutSeconds = 30;
 
-class ResponseImpl : public weave::HttpClient::Response {
+class ResponseImpl : public HttpClient::Response {
  public:
   ~ResponseImpl() override = default;
   explicit ResponseImpl(std::unique_ptr<chromeos::http::Response> response)
       : response_{std::move(response)},
         data_{response_->ExtractDataAsString()} {}
 
-  // weave::HttpClient::Response implementation
+  // HttpClient::Response implementation
   int GetStatusCode() const override { return response_->GetStatusCode(); }
 
   std::string GetContentType() const override {
@@ -41,14 +43,13 @@
   DISALLOW_COPY_AND_ASSIGN(ResponseImpl);
 };
 
-void OnSuccessCallback(
-    const weave::HttpClient::SuccessCallback& success_callback,
-    int id,
-    std::unique_ptr<chromeos::http::Response> response) {
+void OnSuccessCallback(const HttpClient::SuccessCallback& success_callback,
+                       int id,
+                       std::unique_ptr<chromeos::http::Response> response) {
   success_callback.Run(id, ResponseImpl{std::move(response)});
 }
 
-void OnErrorCallback(const weave::HttpClient::ErrorCallback& error_callback,
+void OnErrorCallback(const HttpClient::ErrorCallback& error_callback,
                      int id,
                      const chromeos::Error* chromeos_error) {
   weave::ErrorPtr error;
@@ -66,12 +67,12 @@
 
 HttpTransportClient::~HttpTransportClient() {}
 
-std::unique_ptr<weave::HttpClient::Response>
-HttpTransportClient::SendRequestAndBlock(const std::string& method,
-                                         const std::string& url,
-                                         const Headers& headers,
-                                         const std::string& data,
-                                         weave::ErrorPtr* error) {
+std::unique_ptr<HttpClient::Response> HttpTransportClient::SendRequestAndBlock(
+    const std::string& method,
+    const std::string& url,
+    const Headers& headers,
+    const std::string& data,
+    weave::ErrorPtr* error) {
   chromeos::http::Request request(url, method, transport_);
   request.AddHeaders(headers);
   if (!data.empty()) {
@@ -89,7 +90,7 @@
     return nullptr;
   }
 
-  return std::unique_ptr<weave::HttpClient::Response>{
+  return std::unique_ptr<HttpClient::Response>{
       new ResponseImpl{std::move(response)}};
 }
 
diff --git a/buffet/http_transport_client.h b/buffet/http_transport_client.h
index b44b70e..b02bdfd 100644
--- a/buffet/http_transport_client.h
+++ b/buffet/http_transport_client.h
@@ -8,7 +8,7 @@
 #include <memory>
 #include <string>
 
-#include <weave/http_client.h>
+#include <weave/provider/http_client.h>
 
 namespace chromeos {
 namespace http {
@@ -18,7 +18,7 @@
 
 namespace buffet {
 
-class HttpTransportClient : public weave::HttpClient {
+class HttpTransportClient : public weave::provider::HttpClient {
  public:
   HttpTransportClient();
 
diff --git a/buffet/manager.cc b/buffet/manager.cc
index 787036c..12fd065 100644
--- a/buffet/manager.cc
+++ b/buffet/manager.cc
@@ -51,7 +51,7 @@
 
 }  // anonymous namespace
 
-class Manager::TaskRunner : public weave::TaskRunner {
+class Manager::TaskRunner : public weave::provider::TaskRunner {
  public:
   void PostDelayedTask(const tracked_objects::Location& from_here,
                        const base::Closure& task,
@@ -182,12 +182,12 @@
   auto properties =
       DictionaryFromDBusVariantDictionary(property_set, &chromeos_error);
   if (!properties)
-    response->ReplyWithError(chromeos_error.get());
+    return response->ReplyWithError(chromeos_error.get());
 
   weave::ErrorPtr error;
   if (!device_->GetState()->SetProperties(*properties, &error)) {
     ConvertError(*error, &chromeos_error);
-    response->ReplyWithError(chromeos_error.get());
+    return response->ReplyWithError(chromeos_error.get());
   }
   response->Return();
 }
diff --git a/buffet/mdns_client.h b/buffet/mdns_client.h
index 3743b79..ff7a97a 100644
--- a/buffet/mdns_client.h
+++ b/buffet/mdns_client.h
@@ -24,17 +24,17 @@
 #include <base/guid.h>
 #include <base/memory/ref_counted.h>
 #include <dbus/bus.h>
-#include <weave/dns_service_discovery_provider.h>
+#include <weave/provider/dns_service_discovery.h>
 
 namespace buffet {
 
 // Stub MDNS implementation that does nothing on platform without MDNS support.
-class MdnsClient : public weave::DnsServiceDiscoveryProvider {
+class MdnsClient : public weave::provider::DnsServiceDiscovery {
  public:
   MdnsClient() : device_id_{base::GenerateGUID()} {}
   ~MdnsClient() override = default;
 
-  // weave::Mdns implementation.
+  // weave::provider::DnsServiceDiscovery implementation.
   void PublishService(const std::string& service_type, uint16_t port,
                       const std::vector<std::string>& txt) override {}
   void StopPublishing(const std::string& service_type) override {}
diff --git a/buffet/network_client.h b/buffet/network_client.h
index 81d1e77..82a7476 100644
--- a/buffet/network_client.h
+++ b/buffet/network_client.h
@@ -23,16 +23,16 @@
 
 #include <base/cancelable_callback.h>
 #include <chromeos/errors/error_codes.h>
-#include <weave/network_provider.h>
-#include <weave/wifi_provider.h>
+#include <weave/provider/network.h>
+#include <weave/provider/wifi.h>
 
 #include "buffet/socket_stream.h"
 #include "buffet/weave_error_conversion.h"
 
 namespace buffet {
 
-class NetworkClient : public weave::NetworkProvider,
-                      public weave::WifiProvider {
+class NetworkClient : public weave::provider::Network,
+                      public weave::provider::Wifi {
  public:
   explicit NetworkClient(const std::set<std::string>& device_whitelist)
       : device_whitelist_{device_whitelist} {
@@ -44,8 +44,8 @@
   void AddConnectionChangedCallback(
       const ConnectionChangedCallback& listener) override {}
 
-  weave::NetworkState GetConnectionState() const override {
-    return weave::NetworkState::kOffline;
+  State GetConnectionState() const override {
+    return State::kOffline;
   }
 
   void OpenSslSocket(
diff --git a/buffet/peerd_client.cc b/buffet/peerd_client.cc
index cfbf64a..73b71e4 100644
--- a/buffet/peerd_client.cc
+++ b/buffet/peerd_client.cc
@@ -5,6 +5,7 @@
 #include "buffet/peerd_client.h"
 
 #include <map>
+#include <vector>
 
 #include <base/message_loop/message_loop.h>
 #include <chromeos/errors/error.h>
@@ -27,6 +28,9 @@
   LOG(ERROR) << operation << " failed:" << error->GetMessage();
 }
 
+const char kExpectedServiceType[] = "_privet._tcp";
+const char kServiceName[] = "privet";
+
 }  // namespace
 
 PeerdClient::PeerdClient(const scoped_refptr<dbus::Bus>& bus)
@@ -47,25 +51,20 @@
   return device_id_;
 }
 
-void PeerdClient::PublishService(
-    const std::string& service_name,
-    uint16_t port,
-    const std::map<std::string, std::string>& txt) {
+void PeerdClient::PublishService(const std::string& service_type,
+                                 uint16_t port,
+                                 const std::vector<std::string>& txt) {
   // Only one service supported.
-  CHECK(service_name_.empty() || service_name_ == service_name);
-  service_name_ = service_name;
+  CHECK_EQ(service_type, kExpectedServiceType);
   port_ = port;
   txt_ = txt;
-
   Update();
 }
 
-void PeerdClient::StopPublishing(const std::string& service_name) {
+void PeerdClient::StopPublishing(const std::string& service_type) {
   // Only one service supported.
-  CHECK(service_name_.empty() || service_name_ == service_name);
-  service_name_ = service_name;
+  CHECK_EQ(service_type, kExpectedServiceType);
   port_ = 0;
-
   Update();
 }
 
@@ -117,14 +116,21 @@
     return;
   VLOG(1) << "Starting peerd advertising.";
   CHECK_NE(port_, 0);
-  CHECK(!service_name_.empty());
   CHECK(!txt_.empty());
   std::map<std::string, chromeos::Any> mdns_options{
       {"port", chromeos::Any{port_}},
   };
 
+  std::map<std::string, std::string> txt;
+  for (const auto& record : txt_) {
+    auto name_value = chromeos::string_utils::SplitAtFirst(record, "=");
+    CHECK(!name_value.second.empty());
+    txt.emplace(std::move(name_value));
+  }
+
+  published_ = true;
   peerd_manager_proxy_->ExposeServiceAsync(
-      service_name_, txt_, {{"mdns", mdns_options}}, base::Closure(),
+      kServiceName, txt, {{"mdns", mdns_options}}, base::Closure(),
       base::Bind(&OnError, "ExposeService"));
 }
 
@@ -133,9 +139,10 @@
     return;
 
   VLOG(1) << "Stopping peerd advertising.";
-  if (!service_name_.empty()) {
+  if (published_) {
+    published_ = false;
     peerd_manager_proxy_->RemoveExposedServiceAsync(
-        service_name_, base::Closure(), base::Bind(&OnError, "RemoveService"));
+        kServiceName, base::Closure(), base::Bind(&OnError, "RemoveService"));
   }
 }
 
diff --git a/buffet/peerd_client.h b/buffet/peerd_client.h
index ac75e19..997dcfd 100644
--- a/buffet/peerd_client.h
+++ b/buffet/peerd_client.h
@@ -5,13 +5,13 @@
 #ifndef BUFFET_PEERD_CLIENT_H_
 #define BUFFET_PEERD_CLIENT_H_
 
-#include <map>
 #include <memory>
 #include <string>
+#include <vector>
 
 #include <base/callback.h>
 #include <base/memory/ref_counted.h>
-#include <weave/mdns.h>
+#include <weave/provider/dns_service_discovery.h>
 
 #include "peerd/dbus-proxies.h"
 
@@ -22,16 +22,16 @@
 namespace buffet {
 
 // Publishes privet service on mDns using peerd.
-class PeerdClient : public weave::Mdns {
+class PeerdClient : public weave::provider::DnsServiceDiscovery {
  public:
   explicit PeerdClient(const scoped_refptr<dbus::Bus>& bus);
   ~PeerdClient() override;
 
   // Mdns implementation.
-  void PublishService(const std::string& service_name,
+  void PublishService(const std::string& service_type,
                       uint16_t port,
-                      const std::map<std::string, std::string>& txt) override;
-  void StopPublishing(const std::string& service_name) override;
+                      const std::vector<std::string>& txt) override;
+  void StopPublishing(const std::string& service_type) override;
   std::string GetId() const override;
 
  private:
@@ -56,9 +56,9 @@
   // Cached value of the device ID that we got from peerd.
   std::string device_id_;
 
-  std::string service_name_;
+  bool published_{false};
   uint16_t port_{0};
-  std::map<std::string, std::string> txt_;
+  std::vector<std::string> txt_;
 
   base::WeakPtrFactory<PeerdClient> restart_weak_ptr_factory_{this};
   base::WeakPtrFactory<PeerdClient> weak_ptr_factory_{this};
diff --git a/buffet/shill_client.cc b/buffet/shill_client.cc
index d019011..d3a53f5 100644
--- a/buffet/shill_client.cc
+++ b/buffet/shill_client.cc
@@ -26,11 +26,15 @@
 using std::set;
 using std::string;
 using std::vector;
+using weave::EnumToString;
+using weave::provider::Network;
 
 namespace buffet {
 
 namespace {
 
+const char kErrorDomain[] = "buffet";
+
 void IgnoreDetachEvent() {}
 
 bool GetStateForService(ServiceProxy* service, string* state) {
@@ -54,31 +58,31 @@
   return true;
 }
 
-weave::NetworkState ShillServiceStateToNetworkState(const string& state) {
+Network::State ShillServiceStateToNetworkState(const string& state) {
   // TODO(wiley) What does "unconfigured" mean in a world with multiple sets
   //             of WiFi credentials?
   // TODO(wiley) Detect disabled devices, update state appropriately.
   if ((state.compare(shill::kStateReady) == 0) ||
       (state.compare(shill::kStatePortal) == 0) ||
       (state.compare(shill::kStateOnline) == 0)) {
-    return weave::NetworkState::kConnected;
+    return Network::State::kConnected;
   }
   if ((state.compare(shill::kStateAssociation) == 0) ||
       (state.compare(shill::kStateConfiguration) == 0)) {
-    return weave::NetworkState::kConnecting;
+    return Network::State::kConnecting;
   }
   if ((state.compare(shill::kStateFailure) == 0) ||
       (state.compare(shill::kStateActivationFailure) == 0)) {
     // TODO(wiley) Get error information off the service object.
-    return weave::NetworkState::kFailure;
+    return Network::State::kFailure;
   }
   if ((state.compare(shill::kStateIdle) == 0) ||
       (state.compare(shill::kStateOffline) == 0) ||
       (state.compare(shill::kStateDisconnect) == 0)) {
-    return weave::NetworkState::kOffline;
+    return Network::State::kOffline;
   }
   LOG(WARNING) << "Unknown state found: '" << state << "'";
-  return weave::NetworkState::kOffline;
+  return Network::State::kOffline;
 }
 
 }  // namespace
@@ -86,7 +90,7 @@
 ShillClient::ShillClient(const scoped_refptr<dbus::Bus>& bus,
                          const set<string>& device_whitelist)
     : bus_{bus},
-      manager_proxy_{bus_, ObjectPath{"/"}},
+      manager_proxy_{bus_},
       device_whitelist_{device_whitelist},
       ap_manager_client_{new ApManagerClient(bus)} {
   manager_proxy_.RegisterPropertyChangedSignalHandler(
@@ -104,9 +108,9 @@
 
 void ShillClient::Init() {
   VLOG(2) << "ShillClient::Init();";
-  CleanupConnectingService(false);
+  CleanupConnectingService();
   devices_.clear();
-  connectivity_state_ = weave::NetworkState::kOffline;
+  connectivity_state_ = Network::State::kOffline;
   VariantDictionary properties;
   if (!manager_proxy_.GetProperties(&properties, nullptr)) {
     LOG(ERROR) << "Unable to get properties from Manager, waiting for "
@@ -118,63 +122,84 @@
   OnManagerPropertyChange(shill::kDevicesProperty, it->second);
 }
 
-bool ShillClient::ConnectToService(const string& ssid,
-                                   const string& passphrase,
-                                   const base::Closure& on_success,
-                                   weave::ErrorPtr* error) {
-  chromeos::ErrorPtr chromeos_error;
-  if (!ConnectToServiceImpl(ssid, passphrase, on_success, &chromeos_error)) {
-    ConvertError(*chromeos_error, error);
-    return false;
+void ShillClient::Connect(const string& ssid,
+                          const string& passphrase,
+                          const weave::SuccessCallback& success_callback,
+                          const weave::ErrorCallback& error_callback) {
+  if (connecting_service_) {
+    weave::ErrorPtr error;
+    weave::Error::AddTo(&error, FROM_HERE, kErrorDomain, "busy",
+                        "Already connecting to WiFi network");
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE, base::Bind(error_callback, base::Owned(error.release())));
+    return;
   }
-  return true;
-}
-
-bool ShillClient::ConnectToServiceImpl(const string& ssid,
-                                       const string& passphrase,
-                                       const base::Closure& on_success,
-                                       chromeos::ErrorPtr* error) {
-  CleanupConnectingService(false);
+  CleanupConnectingService();
   VariantDictionary service_properties;
   service_properties[shill::kTypeProperty] = Any{string{shill::kTypeWifi}};
   service_properties[shill::kSSIDProperty] = Any{ssid};
-  service_properties[shill::kPassphraseProperty] = Any{passphrase};
-  service_properties[shill::kSecurityProperty] = Any{
-      string{passphrase.empty() ? shill::kSecurityNone : shill::kSecurityPsk}};
+  if (passphrase.empty()) {
+    service_properties[shill::kSecurityProperty] = Any{shill::kSecurityNone};
+  } else {
+    service_properties[shill::kPassphraseProperty] = Any{passphrase};
+    service_properties[shill::kSecurityProperty] = Any{shill::kSecurityPsk};
+  }
   service_properties[shill::kSaveCredentialsProperty] = Any{true};
   service_properties[shill::kAutoConnectProperty] = Any{true};
   ObjectPath service_path;
+  chromeos::ErrorPtr chromeos_error;
   if (!manager_proxy_.ConfigureService(service_properties, &service_path,
-                                       error)) {
-    return false;
-  }
-  if (!manager_proxy_.RequestScan(shill::kTypeWifi, error)) {
-    return false;
+                                       &chromeos_error) ||
+      !manager_proxy_.RequestScan(shill::kTypeWifi, &chromeos_error)) {
+    weave::ErrorPtr weave_error;
+    ConvertError(*chromeos_error, &weave_error);
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE,
+        base::Bind(error_callback, base::Owned(weave_error.release())));
+    return;
   }
   connecting_service_.reset(new ServiceProxy{bus_, service_path});
-  on_connect_success_.Reset(on_success);
+  connecting_service_->Connect(nullptr);
+  connect_success_callback_ = success_callback;
+  connect_error_callback_ = error_callback;
   connecting_service_->RegisterPropertyChangedSignalHandler(
       base::Bind(&ShillClient::OnServicePropertyChange,
                  weak_factory_.GetWeakPtr(), service_path),
       base::Bind(&ShillClient::OnServicePropertyChangeRegistration,
                  weak_factory_.GetWeakPtr(), service_path));
-  return true;
+  base::MessageLoop::current()->PostDelayedTask(
+      FROM_HERE, base::Bind(&ShillClient::ConnectToServiceError,
+                            weak_factory_.GetWeakPtr(), connecting_service_),
+      base::TimeDelta::FromMinutes(1));
 }
 
-weave::NetworkState ShillClient::GetConnectionState() const {
+void ShillClient::ConnectToServiceError(
+    std::shared_ptr<org::chromium::flimflam::ServiceProxy> connecting_service) {
+  if (connecting_service != connecting_service_ ||
+      connect_error_callback_.is_null()) {
+    return;
+  }
+  std::string error = have_called_connect_ ? connecting_service_error_
+                                           : shill::kErrorOutOfRange;
+  if (error.empty())
+    error = shill::kErrorInternal;
+  OnErrorChangeForConnectingService(error);
+}
+
+Network::State ShillClient::GetConnectionState() const {
   return connectivity_state_;
 }
 
-void ShillClient::EnableAccessPoint(const std::string& ssid) {
+void ShillClient::StartAccessPoint(const std::string& ssid) {
   ap_manager_client_->Start(ssid);
 }
 
-void ShillClient::DisableAccessPoint() {
+void ShillClient::StopAccessPoint() {
   ap_manager_client_->Stop();
 }
 
-void ShillClient::AddOnConnectionChangedCallback(
-    const OnConnectionChangedCallback& listener) {
+void ShillClient::AddConnectionChangedCallback(
+    const ConnectionChangedCallback& listener) {
   connectivity_listeners_.push_back(listener);
 }
 
@@ -199,9 +224,9 @@
                                             const string& new_owner) {
   VLOG(1) << "Shill service owner name changed to '" << new_owner << "'";
   if (new_owner.empty()) {
-    CleanupConnectingService(false);
+    CleanupConnectingService();
     devices_.clear();
-    connectivity_state_ = weave::NetworkState::kOffline;
+    connectivity_state_ = Network::State::kOffline;
   } else {
     Init();  // New service owner means shill reset!
   }
@@ -320,7 +345,7 @@
       return;  // Spurious update?
     }
     device_state.selected_service.reset();
-    device_state.service_state = weave::NetworkState::kOffline;
+    device_state.service_state = Network::State::kOffline;
     removed_old_service = true;
   }
   std::shared_ptr<ServiceProxy> new_service;
@@ -364,9 +389,8 @@
   if (connecting_service_ && connecting_service_->GetObjectPath() == path) {
     // Note that the connecting service might also be a selected service.
     service = connecting_service_.get();
-    if (!success) {
-      CleanupConnectingService(false);
-    }
+    if (!success)
+      CleanupConnectingService();
   } else {
     for (const auto& kv : devices_) {
       if (kv.second.selected_service &&
@@ -385,13 +409,11 @@
   }
   // Give ourselves property changed signals for the initial property
   // values.
-  auto it = properties.find(shill::kStateProperty);
-  if (it != properties.end()) {
-    OnServicePropertyChange(path, shill::kStateProperty, it->second);
-  }
-  it = properties.find(shill::kSignalStrengthProperty);
-  if (it != properties.end()) {
-    OnServicePropertyChange(path, shill::kSignalStrengthProperty, it->second);
+  for (auto name : {shill::kStateProperty, shill::kSignalStrengthProperty,
+                    shill::kErrorProperty}) {
+    auto it = properties.find(name);
+    if (it != properties.end())
+      OnServicePropertyChange(path, name, it->second);
   }
 }
 
@@ -400,6 +422,10 @@
                                           const Any& property_value) {
   VLOG(3) << "ServicePropertyChange(" << service_path.value() << ", "
           << property_name << ", ...);";
+
+  bool is_connecting_service =
+      connecting_service_ &&
+      connecting_service_->GetObjectPath() == service_path;
   if (property_name == shill::kStateProperty) {
     const string state{property_value.TryGet<string>()};
     if (state.empty()) {
@@ -408,33 +434,57 @@
     }
     VLOG(3) << "New service state=" << state;
     OnStateChangeForSelectedService(service_path, state);
-    OnStateChangeForConnectingService(service_path, state);
+    if (is_connecting_service)
+      OnStateChangeForConnectingService(state);
   } else if (property_name == shill::kSignalStrengthProperty) {
-    OnStrengthChangeForConnectingService(service_path,
-                                         property_value.TryGet<uint8_t>());
+    VLOG(3) << "Signal strength=" << property_value.TryGet<uint8_t>();
+    if (is_connecting_service)
+      OnStrengthChangeForConnectingService(property_value.TryGet<uint8_t>());
+  } else if (property_name == shill::kErrorProperty) {
+    VLOG(3) << "Error=" << property_value.TryGet<std::string>();
+    if (is_connecting_service)
+      connecting_service_error_ = property_value.TryGet<std::string>();
   }
 }
 
-void ShillClient::OnStateChangeForConnectingService(
-    const ObjectPath& service_path,
-    const string& state) {
-  if (!connecting_service_ ||
-      connecting_service_->GetObjectPath() != service_path ||
-      ShillServiceStateToNetworkState(state) !=
-          weave::NetworkState::kConnected) {
-    return;
+void ShillClient::OnStateChangeForConnectingService(const string& state) {
+  switch (ShillServiceStateToNetworkState(state)) {
+    case Network::State::kConnected: {
+      auto callback = connect_success_callback_;
+      CleanupConnectingService();
+
+      if (!callback.is_null())
+        callback.Run();
+      break;
+    }
+    case Network::State::kFailure: {
+      ConnectToServiceError(connecting_service_);
+      break;
+    }
+    case Network::State::kOffline:
+    case Network::State::kConnecting:
+      break;
   }
-  connecting_service_reset_pending_ = true;
-  on_connect_success_.callback().Run();
-  CleanupConnectingService(true);
+}
+
+void ShillClient::OnErrorChangeForConnectingService(const std::string& error) {
+  if (error.empty())
+    return;
+
+  auto callback = connect_error_callback_;
+  CleanupConnectingService();
+
+  weave::ErrorPtr weave_error;
+  weave::Error::AddTo(&weave_error, FROM_HERE, kErrorDomain, error,
+                      "Failed to connect to WiFi network");
+
+  if (!callback.is_null())
+    callback.Run(weave_error.get());
 }
 
 void ShillClient::OnStrengthChangeForConnectingService(
-    const ObjectPath& service_path,
     uint8_t signal_strength) {
-  if (!connecting_service_ ||
-      connecting_service_->GetObjectPath() != service_path ||
-      signal_strength <= 0 || have_called_connect_) {
+  if (signal_strength == 0 || have_called_connect_) {
     return;
   }
   VLOG(1) << "Connecting service has signal. Calling Connect().";
@@ -466,7 +516,7 @@
 void ShillClient::UpdateConnectivityState() {
   // Update the connectivity state of the device by picking the
   // state of the currently most connected selected service.
-  weave::NetworkState new_connectivity_state{weave::NetworkState::kOffline};
+  Network::State new_connectivity_state{Network::State::kOffline};
   for (const auto& kv : devices_) {
     if (kv.second.service_state > new_connectivity_state) {
       new_connectivity_state = kv.second.service_state;
@@ -486,42 +536,45 @@
       FROM_HERE,
       base::Bind(&ShillClient::NotifyConnectivityListeners,
                  weak_factory_.GetWeakPtr(),
-                 GetConnectionState() == weave::NetworkState::kConnected));
+                 GetConnectionState() == Network::State::kConnected));
 }
 
 void ShillClient::NotifyConnectivityListeners(bool am_online) {
   VLOG(3) << "Notifying connectivity listeners that online=" << am_online;
-  for (const auto& listener : connectivity_listeners_) {
-    listener.Run(am_online);
-  }
+  for (const auto& listener : connectivity_listeners_)
+    listener.Run();
 }
 
-void ShillClient::CleanupConnectingService(bool check_for_reset_pending) {
-  if (check_for_reset_pending && !connecting_service_reset_pending_) {
-    return;  // Must have called connect before we got here.
-  }
+void ShillClient::CleanupConnectingService() {
   if (connecting_service_) {
     connecting_service_->ReleaseObjectProxy(base::Bind(&IgnoreDetachEvent));
     connecting_service_.reset();
   }
-  on_connect_success_.Cancel();
+  connect_success_callback_.Reset();
+  connect_error_callback_.Reset();
   have_called_connect_ = false;
-  connecting_service_reset_pending_ = false;
 }
 
-std::unique_ptr<weave::Stream> ShillClient::OpenSocketBlocking(
+void ShillClient::OpenSslSocket(
     const std::string& host,
-    uint16_t port) {
-  return SocketStream::ConnectBlocking(host, port);
-}
-
-void ShillClient::CreateTlsStream(
-    std::unique_ptr<weave::Stream> socket,
-    const std::string& host,
+    uint16_t port,
     const base::Callback<void(std::unique_ptr<weave::Stream>)>&
         success_callback,
     const base::Callback<void(const weave::Error*)>& error_callback) {
-  SocketStream::TlsConnect(std::move(socket), host, success_callback,
+  std::unique_ptr<weave::Stream> raw_stream{
+      SocketStream::ConnectBlocking(host, port)};
+  if (!raw_stream) {
+    chromeos::ErrorPtr error;
+    chromeos::errors::system::AddSystemError(&error, FROM_HERE, errno);
+    weave::ErrorPtr weave_error;
+    ConvertError(*error.get(), &weave_error);
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE,
+        base::Bind(error_callback, base::Owned(weave_error.release())));
+    return;
+  }
+
+  SocketStream::TlsConnect(std::move(raw_stream), host, success_callback,
                            error_callback);
 }
 
diff --git a/buffet/shill_client.h b/buffet/shill_client.h
index 6f14226..2e4dc2c 100644
--- a/buffet/shill_client.h
+++ b/buffet/shill_client.h
@@ -16,15 +16,16 @@
 #include <base/memory/ref_counted.h>
 #include <base/memory/weak_ptr.h>
 #include <dbus/bus.h>
-#include <weave/network.h>
-
-#include "shill/dbus-proxies.h"
+#include <shill/dbus-proxies.h>
+#include <weave/provider/network.h>
+#include <weave/provider/wifi.h>
 
 namespace buffet {
 
 class ApManagerClient;
 
-class ShillClient final : public weave::Network {
+class ShillClient final : public weave::provider::Network,
+                          public weave::provider::Wifi {
  public:
   ShillClient(const scoped_refptr<dbus::Bus>& bus,
               const std::set<std::string>& device_whitelist);
@@ -32,24 +33,23 @@
 
   void Init();
 
-  // Network implementation.
-  void AddOnConnectionChangedCallback(
-      const OnConnectionChangedCallback& listener) override;
-  bool ConnectToService(const std::string& ssid,
-                        const std::string& passphrase,
-                        const base::Closure& on_success,
-                        weave::ErrorPtr* error) override;
-  weave::NetworkState GetConnectionState() const override;
-  void EnableAccessPoint(const std::string& ssid) override;
-  void DisableAccessPoint() override;
-  std::unique_ptr<weave::Stream> OpenSocketBlocking(const std::string& host,
-                                                    uint16_t port) override;
-  void CreateTlsStream(
-      std::unique_ptr<weave::Stream> socket,
-      const std::string& host,
-      const base::Callback<void(std::unique_ptr<weave::Stream>)>&
-          success_callback,
-      const base::Callback<void(const weave::Error*)>& error_callback) override;
+  // NetworkProvider implementation.
+  void AddConnectionChangedCallback(
+      const ConnectionChangedCallback& listener) override;
+  State GetConnectionState() const override;
+  void OpenSslSocket(const std::string& host,
+                     uint16_t port,
+                     const base::Callback<void(std::unique_ptr<weave::Stream>)>&
+                         success_callback,
+                     const weave::ErrorCallback& error_callback) override;
+
+  // WifiProvider implementation.
+  void Connect(const std::string& ssid,
+               const std::string& passphrase,
+               const weave::SuccessCallback& success_callback,
+               const weave::ErrorCallback& error_callback) override;
+  void StartAccessPoint(const std::string& ssid) override;
+  void StopAccessPoint() override;
 
  private:
   struct DeviceState {
@@ -59,7 +59,7 @@
     // service (for instance, in the period between configuring a WiFi service
     // with credentials, and when Connect() is called.)
     std::shared_ptr<org::chromium::flimflam::ServiceProxy> selected_service;
-    weave::NetworkState service_state{weave::NetworkState::kOffline};
+    State service_state{State::kOffline};
   };
 
   bool IsMonitoredDevice(org::chromium::flimflam::DeviceProxy* device);
@@ -85,42 +85,37 @@
                                const std::string& property_name,
                                const chromeos::Any& property_value);
 
-  void OnStateChangeForConnectingService(const dbus::ObjectPath& service_path,
-                                         const std::string& state);
-  void OnStrengthChangeForConnectingService(
-      const dbus::ObjectPath& service_path,
-      uint8_t signal_strength);
+  void OnStateChangeForConnectingService(const std::string& state);
+  void OnErrorChangeForConnectingService(const std::string& error);
+  void OnStrengthChangeForConnectingService(uint8_t signal_strength);
   void OnStateChangeForSelectedService(const dbus::ObjectPath& service_path,
                                        const std::string& state);
   void UpdateConnectivityState();
   void NotifyConnectivityListeners(bool am_online);
-  // Clean up state related to a connecting service.  If
-  // |check_for_reset_pending| is set, then we'll check to see if we've called
-  // ConnectToService() in the time since a task to call this function was
-  // posted.
-  void CleanupConnectingService(bool check_for_reset_pending);
+  // Clean up state related to a connecting service.
+  void CleanupConnectingService();
 
-  bool ConnectToServiceImpl(const std::string& ssid,
-                            const std::string& passphrase,
-                            const base::Closure& on_success,
-                            chromeos::ErrorPtr* error);
+  void ConnectToServiceError(
+      std::shared_ptr<org::chromium::flimflam::ServiceProxy>
+          connecting_service);
 
   const scoped_refptr<dbus::Bus> bus_;
   org::chromium::flimflam::ManagerProxy manager_proxy_;
   // There is logic that assumes we will never change this device list
   // in OnManagerPropertyChange.  Do not be tempted to remove this const.
   const std::set<std::string> device_whitelist_;
-  std::vector<OnConnectionChangedCallback> connectivity_listeners_;
+  std::vector<ConnectionChangedCallback> connectivity_listeners_;
 
   // State for tracking where we are in our attempts to connect to a service.
-  bool connecting_service_reset_pending_{false};
   bool have_called_connect_{false};
   std::shared_ptr<org::chromium::flimflam::ServiceProxy> connecting_service_;
-  base::CancelableClosure on_connect_success_;
+  std::string connecting_service_error_;
+  base::Closure connect_success_callback_;
+  base::Callback<void(const weave::Error*)> connect_error_callback_;
 
   // State for tracking our online connectivity.
   std::map<dbus::ObjectPath, DeviceState> devices_;
-  weave::NetworkState connectivity_state_{weave::NetworkState::kOffline};
+  State connectivity_state_{State::kOffline};
 
   std::unique_ptr<ApManagerClient> ap_manager_client_;
 
diff --git a/buffet/webserv_client.cc b/buffet/webserv_client.cc
index f165849..e79a6a4 100644
--- a/buffet/webserv_client.cc
+++ b/buffet/webserv_client.cc
@@ -19,7 +19,9 @@
 
 namespace {
 
-class RequestImpl : public weave::HttpServer::Request {
+using weave::provider::HttpServer;
+
+class RequestImpl : public HttpServer::Request {
  public:
   explicit RequestImpl(std::unique_ptr<libwebserv::Request> request)
       : request_{std::move(request)} {}
@@ -27,6 +29,7 @@
 
   // HttpServer::Request implementation.
   const std::string& GetPath() const override { return request_->GetPath(); }
+
   std::string GetFirstHeader(const std::string& name) const override {
     return request_->GetFirstHeader(name);
   }
diff --git a/buffet/webserv_client.h b/buffet/webserv_client.h
index 8457d8b..0b47527 100644
--- a/buffet/webserv_client.h
+++ b/buffet/webserv_client.h
@@ -10,7 +10,7 @@
 #include <vector>
 
 #include <base/memory/weak_ptr.h>
-#include <weave/http_server.h>
+#include <weave/provider/http_server.h>
 
 namespace dbus {
 class Bus;
@@ -32,7 +32,7 @@
 namespace buffet {
 
 // Wrapper around libwebserv that implements HttpServer interface.
-class WebServClient : public weave::HttpServer {
+class WebServClient : public weave::provider::HttpServer {
  public:
   WebServClient(const scoped_refptr<dbus::Bus>& bus,
                 chromeos::dbus_utils::AsyncEventSequencer* sequencer);