buffet: Move privetd sources into buffet

No functional changes, only renaming, fixed include paths and include
guards to avoid resubmit warnings.

BUG=brillo:1161
CQ-DEPEND=CL:276521
TEST=none

Change-Id: Icacff92aef47fdd46542bc96eba3ffbb4df6241a
Reviewed-on: https://chromium-review.googlesource.com/276319
Reviewed-by: Vitaly Buka <vitalybuka@chromium.org>
Commit-Queue: Vitaly Buka <vitalybuka@chromium.org>
Tested-by: Vitaly Buka <vitalybuka@chromium.org>
diff --git a/buffet/privet/peerd_client.cc b/buffet/privet/peerd_client.cc
new file mode 100644
index 0000000..76f88ce
--- /dev/null
+++ b/buffet/privet/peerd_client.cc
@@ -0,0 +1,170 @@
+// Copyright 2014 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 "buffet/privet/peerd_client.h"
+
+#include <map>
+
+#include <base/message_loop/message_loop.h>
+#include <chromeos/errors/error.h>
+#include <chromeos/strings/string_utils.h>
+
+#include "buffet/privet/cloud_delegate.h"
+#include "buffet/privet/device_delegate.h"
+#include "buffet/privet/wifi_bootstrap_manager.h"
+#include "buffet/privet/wifi_ssid_generator.h"
+
+using chromeos::string_utils::Join;
+using org::chromium::peerd::PeerProxy;
+
+namespace privetd {
+
+namespace {
+
+// Commit changes only if no update request happened during the timeout.
+// Usually updates happen in batches, so we don't want to flood network with
+// 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) {
+  LOG(ERROR) << operation << " failed:" << error->GetMessage();
+}
+
+}  // 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_);
+  peerd_object_manager_proxy_.SetManagerAddedCallback(
+      base::Bind(&PeerdClient::OnPeerdOnline, weak_ptr_factory_.GetWeakPtr()));
+  peerd_object_manager_proxy_.SetManagerRemovedCallback(
+      base::Bind(&PeerdClient::OnPeerdOffline, weak_ptr_factory_.GetWeakPtr()));
+  peerd_object_manager_proxy_.SetPeerAddedCallback(
+      base::Bind(&PeerdClient::OnNewPeer, weak_ptr_factory_.GetWeakPtr()));
+}
+
+PeerdClient::~PeerdClient() {
+  RemoveService();
+}
+
+std::string PeerdClient::GetId() const {
+  return device_id_;
+}
+
+void PeerdClient::Update() {
+  // Abort pending updates, and wait for more changes.
+  restart_weak_ptr_factory_.InvalidateWeakPtrs();
+  base::MessageLoop::current()->PostDelayedTask(
+      FROM_HERE, base::Bind(&PeerdClient::UpdateImpl,
+                            restart_weak_ptr_factory_.GetWeakPtr()),
+      base::TimeDelta::FromSeconds(kCommitTimeoutSeconds));
+}
+
+void PeerdClient::OnNewPeer(PeerProxy* peer) {
+  if (!peer || peer->GetObjectPath().value() != kSelfPath)
+    return;
+  peer->SetPropertyChangedCallback(
+      base::Bind(&PeerdClient::OnPeerPropertyChanged,
+                 weak_ptr_factory_.GetWeakPtr()));
+  OnPeerPropertyChanged(peer, PeerProxy::UUIDName());
+}
+
+void PeerdClient::OnPeerPropertyChanged(
+    PeerProxy* peer,
+    const std::string& property_name) {
+  if (property_name != PeerProxy::UUIDName() ||
+      peer->GetObjectPath().value() != kSelfPath)
+    return;
+  const std::string new_id{peer->uuid()};
+  if (new_id != device_id_) {
+    device_id_ = new_id;
+    Update();
+  }
+}
+
+void PeerdClient::OnPeerdOnline(
+    org::chromium::peerd::ManagerProxy* manager_proxy) {
+  peerd_manager_proxy_ = manager_proxy;
+  VLOG(1) << "Peerd manager is online at '"
+          << manager_proxy->GetObjectPath().value() << "'.";
+  Update();
+}
+
+void PeerdClient::OnPeerdOffline(const dbus::ObjectPath& object_path) {
+  peerd_manager_proxy_ = nullptr;
+  VLOG(1) << "Peerd manager is now offline.";
+}
+
+void PeerdClient::ExposeService() {
+  // 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;
+  std::map<std::string, chromeos::Any> mdns_options{
+      {"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(),
+      base::Bind(&OnError, "ExposeService"));
+}
+
+void PeerdClient::RemoveService() {
+  if (peerd_manager_proxy_ == nullptr)
+    return;
+
+  VLOG(1) << "Stopping peerd advertising.";
+  peerd_manager_proxy_->RemoveExposedServiceAsync(
+      kPrivetServiceId, base::Closure(), base::Bind(&OnError, "RemoveService"));
+}
+
+void PeerdClient::UpdateImpl() {
+  if (device_->GetHttpEnpoint().first == 0)
+    return RemoveService();
+  ExposeService();
+}
+
+}  // namespace privetd