libweave: Extract platform independent part of PeerdClient
The rest of PeerdClinet will be moved into buffet.
BUG=brillo:1267
TEST='FEATURES=test emerge-gizmo buffet'
Change-Id: I884cfe377334f8d3fced5a493de8d407bb6bd3ca
Reviewed-on: https://chromium-review.googlesource.com/289945
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Vitaly Buka <vitalybuka@chromium.org>
Trybot-Ready: Vitaly Buka <vitalybuka@chromium.org>
Tested-by: Vitaly Buka <vitalybuka@chromium.org>
diff --git a/buffet/buffet.gyp b/buffet/buffet.gyp
index 8d22323..a679314 100644
--- a/buffet/buffet.gyp
+++ b/buffet/buffet.gyp
@@ -64,6 +64,7 @@
'../libweave/src/privet/privet_handler.cc',
'../libweave/src/privet/privet_manager.cc',
'../libweave/src/privet/privet_types.cc',
+ '../libweave/src/privet/publisher.cc',
'../libweave/src/privet/security_manager.cc',
'../libweave/src/privet/shill_client.cc',
'../libweave/src/privet/privet_types.cc',
diff --git a/libweave/include/weave/mdns.h b/libweave/include/weave/mdns.h
new file mode 100644
index 0000000..d1b7232
--- /dev/null
+++ b/libweave/include/weave/mdns.h
@@ -0,0 +1,36 @@
+// Copyright 2015 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 LIBWEAVE_INCLUDE_WEAVE_MDNS_H_
+#define LIBWEAVE_INCLUDE_WEAVE_MDNS_H_
+
+#include <map>
+#include <string>
+
+#include <base/callback.h>
+
+namespace weave {
+
+class Mdns {
+ public:
+ // Publishes new service on mDns or updates existing one.
+ virtual void PublishService(
+ const std::string& service_name,
+ uint16_t port,
+ const std::map<std::string, std::string>& txt) = 0;
+
+ // Stops publishing service.
+ virtual void StopPublishing(const std::string& service_name) = 0;
+
+ // Returns permanent device ID.
+ // TODO(vitalybuka): Find better place for this information.
+ virtual std::string GetId() const = 0;
+
+ protected:
+ virtual ~Mdns() = default;
+};
+
+} // namespace weave
+
+#endif // LIBWEAVE_INCLUDE_WEAVE_MDNS_H_
diff --git a/libweave/src/privet/peerd_client.cc b/libweave/src/privet/peerd_client.cc
index d37740e..1ed7796 100644
--- a/libweave/src/privet/peerd_client.cc
+++ b/libweave/src/privet/peerd_client.cc
@@ -10,12 +10,6 @@
#include <chromeos/errors/error.h>
#include <chromeos/strings/string_utils.h>
-#include "libweave/src/privet/cloud_delegate.h"
-#include "libweave/src/privet/device_delegate.h"
-#include "libweave/src/privet/wifi_bootstrap_manager.h"
-#include "libweave/src/privet/wifi_ssid_generator.h"
-
-using chromeos::string_utils::Join;
using org::chromium::peerd::PeerProxy;
namespace weave {
@@ -28,8 +22,6 @@
// updates relevant for a short amount of time.
const int kCommitTimeoutSeconds = 1;
-// The name of the service we'll expose via peerd.
-const char kPrivetServiceId[] = "privet";
const char kSelfPath[] = "/org/chromium/peerd/Self";
void OnError(const std::string& operation, chromeos::Error* error) {
@@ -38,16 +30,8 @@
} // namespace
-PeerdClient::PeerdClient(const scoped_refptr<dbus::Bus>& bus,
- const DeviceDelegate* device,
- const CloudDelegate* cloud,
- const WifiDelegate* wifi)
- : peerd_object_manager_proxy_{bus},
- device_{device},
- cloud_{cloud},
- wifi_{wifi} {
- CHECK(device_);
- CHECK(cloud_);
+PeerdClient::PeerdClient(const scoped_refptr<dbus::Bus>& bus)
+ : peerd_object_manager_proxy_{bus} {
peerd_object_manager_proxy_.SetManagerAddedCallback(
base::Bind(&PeerdClient::OnPeerdOnline, weak_ptr_factory_.GetWeakPtr()));
peerd_object_manager_proxy_.SetManagerRemovedCallback(
@@ -64,6 +48,28 @@
return device_id_;
}
+void PeerdClient::PublishService(
+ const std::string& service_name,
+ uint16_t port,
+ const std::map<std::string, std::string>& txt) {
+ // Only one service supported.
+ CHECK(service_name_.empty() || service_name_ == service_name);
+ service_name_ = service_name;
+ port_ = port;
+ txt_ = txt;
+
+ Update();
+}
+
+void PeerdClient::StopPublishing(const std::string& service_name) {
+ // Only one service supported.
+ CHECK(service_name_.empty() || service_name_ == service_name);
+ service_name_ = service_name;
+ port_ = 0;
+
+ Update();
+}
+
void PeerdClient::Update() {
// Abort pending updates, and wait for more changes.
restart_weak_ptr_factory_.InvalidateWeakPtrs();
@@ -110,44 +116,16 @@
// Do nothing if peerd hasn't started yet.
if (peerd_manager_proxy_ == nullptr)
return;
-
- std::string name;
- std::string model_id;
- if (!cloud_->GetName(&name, nullptr) ||
- !cloud_->GetModelId(&model_id, nullptr)) {
- return;
- }
- DCHECK_EQ(model_id.size(), 5U);
-
VLOG(1) << "Starting peerd advertising.";
- const uint16_t port = device_->GetHttpEnpoint().first;
+ CHECK_NE(port_, 0);
+ CHECK(!service_name_.empty());
+ CHECK(!txt_.empty());
std::map<std::string, chromeos::Any> mdns_options{
- {"port", chromeos::Any{port}},
+ {"port", chromeos::Any{port_}},
};
- DCHECK_NE(port, 0);
-
- std::string services;
- if (!cloud_->GetServices().empty())
- services += "_";
- services += Join(",_", cloud_->GetServices());
-
- std::map<std::string, std::string> txt_record{
- {"txtvers", "3"},
- {"ty", name},
- {"services", services},
- {"id", GetId()},
- {"mmid", model_id},
- {"flags", WifiSsidGenerator{cloud_, wifi_}.GenerateFlags()},
- };
-
- if (!cloud_->GetCloudId().empty())
- txt_record.emplace("gcd_id", cloud_->GetCloudId());
-
- if (!cloud_->GetDescription().empty())
- txt_record.emplace("note", cloud_->GetDescription());
peerd_manager_proxy_->ExposeServiceAsync(
- kPrivetServiceId, txt_record, {{"mdns", mdns_options}}, base::Closure(),
+ service_name_, txt_, {{"mdns", mdns_options}}, base::Closure(),
base::Bind(&OnError, "ExposeService"));
}
@@ -156,12 +134,14 @@
return;
VLOG(1) << "Stopping peerd advertising.";
- peerd_manager_proxy_->RemoveExposedServiceAsync(
- kPrivetServiceId, base::Closure(), base::Bind(&OnError, "RemoveService"));
+ if (!service_name_.empty()) {
+ peerd_manager_proxy_->RemoveExposedServiceAsync(
+ service_name_, base::Closure(), base::Bind(&OnError, "RemoveService"));
+ }
}
void PeerdClient::UpdateImpl() {
- if (device_->GetHttpEnpoint().first == 0)
+ if (port_ == 0)
return RemoveService();
ExposeService();
}
diff --git a/libweave/src/privet/peerd_client.h b/libweave/src/privet/peerd_client.h
index b75e253..de90248 100644
--- a/libweave/src/privet/peerd_client.h
+++ b/libweave/src/privet/peerd_client.h
@@ -5,14 +5,15 @@
#ifndef LIBWEAVE_SRC_PRIVET_PEERD_CLIENT_H_
#define LIBWEAVE_SRC_PRIVET_PEERD_CLIENT_H_
+#include <map>
#include <memory>
#include <string>
#include <base/callback.h>
#include <base/memory/ref_counted.h>
-#include "libweave/src/privet/identity_delegate.h"
#include "peerd/dbus-proxies.h"
+#include "weave/mdns.h"
namespace dbus {
class Bus;
@@ -21,26 +22,19 @@
namespace weave {
namespace privet {
-class CloudDelegate;
-class DeviceDelegate;
-class WifiDelegate;
-
-// Publishes prived service on mDns using peerd.
-class PeerdClient : public IdentityDelegate {
+// Publishes privet service on mDns using peerd.
+class PeerdClient : public Mdns {
public:
- PeerdClient(const scoped_refptr<dbus::Bus>& bus,
- const DeviceDelegate* device,
- const CloudDelegate* cloud,
- const WifiDelegate* wifi);
- ~PeerdClient();
+ explicit PeerdClient(const scoped_refptr<dbus::Bus>& bus);
+ ~PeerdClient() override;
- // Get the unique identifier for this device. Note that if peerd has
- // never been seen, this may be the empty string.
+ // Mdns implementation.
+ void PublishService(const std::string& service_name,
+ uint16_t port,
+ const std::map<std::string, std::string>& txt) override;
+ void StopPublishing(const std::string& service_name) override;
std::string GetId() const override;
- // Updates published information. Removes service if HTTP is not alive.
- void Update();
-
private:
void OnPeerdOnline(org::chromium::peerd::ManagerProxy* manager_proxy);
void OnPeerdOffline(const dbus::ObjectPath& object_path);
@@ -48,6 +42,9 @@
void OnPeerPropertyChanged(org::chromium::peerd::PeerProxy* peer_proxy,
const std::string& property_name);
+ // Updates published information. Removes service if HTTP is not alive.
+ void Update();
+
void ExposeService();
void RemoveService();
@@ -57,15 +54,17 @@
// |peerd_manager_proxy_| is owned by |peerd_object_manager_proxy_|.
org::chromium::peerd::ManagerProxy* peerd_manager_proxy_{nullptr};
- const DeviceDelegate* device_{nullptr};
- const CloudDelegate* cloud_{nullptr};
- const WifiDelegate* wifi_{nullptr};
-
// Cached value of the device ID that we got from peerd.
std::string device_id_;
+ std::string service_name_;
+ uint16_t port_{0};
+ std::map<std::string, std::string> txt_;
+
base::WeakPtrFactory<PeerdClient> restart_weak_ptr_factory_{this};
base::WeakPtrFactory<PeerdClient> weak_ptr_factory_{this};
+
+ DISALLOW_COPY_AND_ASSIGN(PeerdClient);
};
} // namespace privet
diff --git a/libweave/src/privet/privet_manager.cc b/libweave/src/privet/privet_manager.cc
index 698283a..b65ba06 100644
--- a/libweave/src/privet/privet_manager.cc
+++ b/libweave/src/privet/privet_manager.cc
@@ -35,6 +35,7 @@
#include "libweave/src/privet/device_delegate.h"
#include "libweave/src/privet/peerd_client.h"
#include "libweave/src/privet/privet_handler.h"
+#include "libweave/src/privet/publisher.h"
#include "libweave/src/privet/shill_client.h"
namespace weave {
@@ -88,12 +89,15 @@
wifi_bootstrap_manager_->Init();
}
- peerd_client_.reset(new PeerdClient(bus, device_.get(), cloud_.get(),
- wifi_bootstrap_manager_.get()));
+ peerd_client_.reset(new PeerdClient(bus));
+
+ publisher_.reset(new Publisher(device_.get(), cloud_.get(),
+ wifi_bootstrap_manager_.get(),
+ peerd_client_.get()));
privet_handler_.reset(
new PrivetHandler(cloud_.get(), device_.get(), security_.get(),
- wifi_bootstrap_manager_.get(), peerd_client_.get()));
+ wifi_bootstrap_manager_.get(), publisher_.get()));
web_server_.reset(new libwebserv::Server);
web_server_->OnProtocolHandlerConnected(base::Bind(
@@ -195,8 +199,8 @@
}
void Manager::OnChanged() {
- if (peerd_client_)
- peerd_client_->Update();
+ if (publisher_)
+ publisher_->Update();
}
void Manager::OnConnectivityChanged(bool online) {
@@ -206,8 +210,8 @@
void Manager::OnProtocolHandlerConnected(ProtocolHandler* protocol_handler) {
if (protocol_handler->GetName() == ProtocolHandler::kHttp) {
device_->SetHttpPort(*protocol_handler->GetPorts().begin());
- if (peerd_client_)
- peerd_client_->Update();
+ if (publisher_)
+ publisher_->Update();
} else if (protocol_handler->GetName() == ProtocolHandler::kHttps) {
device_->SetHttpsPort(*protocol_handler->GetPorts().begin());
security_->SetCertificateFingerprint(
@@ -218,8 +222,8 @@
void Manager::OnProtocolHandlerDisconnected(ProtocolHandler* protocol_handler) {
if (protocol_handler->GetName() == ProtocolHandler::kHttp) {
device_->SetHttpPort(0);
- if (peerd_client_)
- peerd_client_->Update();
+ if (publisher_)
+ publisher_->Update();
} else if (protocol_handler->GetName() == ProtocolHandler::kHttps) {
device_->SetHttpsPort(0);
security_->SetCertificateFingerprint({});
diff --git a/libweave/src/privet/privet_manager.h b/libweave/src/privet/privet_manager.h
index 9ec3984..cb77b12 100644
--- a/libweave/src/privet/privet_manager.h
+++ b/libweave/src/privet/privet_manager.h
@@ -35,6 +35,7 @@
class CommandManager;
class DeviceRegistrationInfo;
+class Mdns;
class StateManager;
namespace privet {
@@ -45,6 +46,7 @@
class DeviceDelegate;
class PeerdClient;
class PrivetHandler;
+class Publisher;
class SecurityManager;
class ShillClient;
@@ -102,6 +104,7 @@
std::unique_ptr<ApManagerClient> ap_manager_client_;
std::unique_ptr<WifiBootstrapManager> wifi_bootstrap_manager_;
std::unique_ptr<PeerdClient> peerd_client_;
+ std::unique_ptr<Publisher> publisher_;
std::unique_ptr<PrivetHandler> privet_handler_;
std::unique_ptr<libwebserv::Server> web_server_;
diff --git a/libweave/src/privet/publisher.cc b/libweave/src/privet/publisher.cc
new file mode 100644
index 0000000..877aa02
--- /dev/null
+++ b/libweave/src/privet/publisher.cc
@@ -0,0 +1,96 @@
+// Copyright 2015 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 "libweave/src/privet/publisher.h"
+
+#include <map>
+
+#include <chromeos/errors/error.h>
+#include <chromeos/strings/string_utils.h>
+
+#include "libweave/src/privet/cloud_delegate.h"
+#include "libweave/src/privet/device_delegate.h"
+#include "libweave/src/privet/wifi_bootstrap_manager.h"
+#include "libweave/src/privet/wifi_ssid_generator.h"
+#include "weave/mdns.h"
+
+using chromeos::string_utils::Join;
+
+namespace weave {
+namespace privet {
+
+namespace {
+
+// The name of the service we'll expose via peerd.
+const char kPrivetServiceId[] = "privet";
+
+} // namespace
+
+Publisher::Publisher(const DeviceDelegate* device,
+ const CloudDelegate* cloud,
+ const WifiDelegate* wifi,
+ Mdns* mdns)
+ : mdns_{mdns}, device_{device}, cloud_{cloud}, wifi_{wifi} {
+ CHECK(device_);
+ CHECK(cloud_);
+ CHECK(mdns_);
+}
+
+Publisher::~Publisher() {
+ RemoveService();
+}
+
+std::string Publisher::GetId() const {
+ return mdns_->GetId();
+}
+
+void Publisher::Update() {
+ if (device_->GetHttpEnpoint().first == 0)
+ return RemoveService();
+ ExposeService();
+}
+
+void Publisher::ExposeService() {
+ std::string name;
+ std::string model_id;
+ if (!cloud_->GetName(&name, nullptr) ||
+ !cloud_->GetModelId(&model_id, nullptr)) {
+ return;
+ }
+ DCHECK_EQ(model_id.size(), 5U);
+
+ VLOG(1) << "Starting peerd advertising.";
+ const uint16_t port = device_->GetHttpEnpoint().first;
+ DCHECK_NE(port, 0);
+
+ std::string services;
+ if (!cloud_->GetServices().empty())
+ services += "_";
+ services += Join(",_", cloud_->GetServices());
+
+ std::map<std::string, std::string> txt_record{
+ {"txtvers", "3"},
+ {"ty", name},
+ {"services", services},
+ {"id", GetId()},
+ {"mmid", model_id},
+ {"flags", WifiSsidGenerator{cloud_, wifi_}.GenerateFlags()},
+ };
+
+ if (!cloud_->GetCloudId().empty())
+ txt_record.emplace("gcd_id", cloud_->GetCloudId());
+
+ if (!cloud_->GetDescription().empty())
+ txt_record.emplace("note", cloud_->GetDescription());
+
+ mdns_->PublishService(kPrivetServiceId, port, txt_record);
+}
+
+void Publisher::RemoveService() {
+ VLOG(1) << "Stopping service publishing.";
+ mdns_->StopPublishing(kPrivetServiceId);
+}
+
+} // namespace privet
+} // namespace weave
diff --git a/libweave/src/privet/publisher.h b/libweave/src/privet/publisher.h
new file mode 100644
index 0000000..1655ae1
--- /dev/null
+++ b/libweave/src/privet/publisher.h
@@ -0,0 +1,60 @@
+// Copyright 2015 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 LIBWEAVE_SRC_PRIVET_PUBLISHER_H_
+#define LIBWEAVE_SRC_PRIVET_PUBLISHER_H_
+
+#include <memory>
+#include <string>
+
+#include <base/macros.h>
+
+#include "libweave/src/privet/identity_delegate.h"
+
+namespace dbus {
+class Bus;
+} // namespace dbus
+
+namespace weave {
+
+class Mdns;
+
+namespace privet {
+
+class CloudDelegate;
+class DeviceDelegate;
+class WifiDelegate;
+
+// Publishes privet service on mDns.
+class Publisher : public IdentityDelegate {
+ public:
+ Publisher(const DeviceDelegate* device,
+ const CloudDelegate* cloud,
+ const WifiDelegate* wifi,
+ Mdns* mdns);
+ ~Publisher() override;
+
+ // IdentityDelegate implementation.
+ std::string GetId() const override;
+
+ // Updates published information. Removes service if HTTP is not alive.
+ void Update();
+
+ private:
+ void ExposeService();
+ void RemoveService();
+
+ Mdns* mdns_{nullptr};
+
+ const DeviceDelegate* device_{nullptr};
+ const CloudDelegate* cloud_{nullptr};
+ const WifiDelegate* wifi_{nullptr};
+
+ DISALLOW_COPY_AND_ASSIGN(Publisher);
+};
+
+} // namespace privet
+} // namespace weave
+
+#endif // LIBWEAVE_SRC_PRIVET_PUBLISHER_H_