普通文本  |  93行  |  2.38 KB

// Copyright 2015 The Weave 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/privet/publisher.h"

#include <map>

#include <weave/error.h>
#include <weave/provider/dns_service_discovery.h>

#include "src/privet/cloud_delegate.h"
#include "src/privet/device_delegate.h"
#include "src/privet/device_ui_kind.h"
#include "src/privet/wifi_bootstrap_manager.h"
#include "src/privet/wifi_ssid_generator.h"
#include "src/string_utils.h"

namespace weave {
namespace privet {

namespace {

// The service type we'll expose via DNS-SD.
const char kPrivetServiceType[] = "_privet._tcp";

}  // namespace

Publisher::Publisher(const DeviceDelegate* device,
                     const CloudDelegate* cloud,
                     const WifiDelegate* wifi,
                     provider::DnsServiceDiscovery* dns_sd)
    : dns_sd_{dns_sd}, device_{device}, cloud_{cloud}, wifi_{wifi} {
  CHECK(device_);
  CHECK(cloud_);
  CHECK(dns_sd_);
  Update();
}

Publisher::~Publisher() {
  RemoveService();
}

void Publisher::Update() {
  if (device_->GetHttpEnpoint().first == 0)
    return RemoveService();
  ExposeService();
}

void Publisher::ExposeService() {
  std::string name{cloud_->GetName()};
  std::string model_id{cloud_->GetModelId()};
  DCHECK_EQ(model_id.size(), 5U);

  VLOG(2) << "DNS-SD update requested";
  const uint16_t port = device_->GetHttpEnpoint().first;
  DCHECK_NE(port, 0);

  std::vector<std::string> txt_record{
      {"txtvers=3"},
      {"ty=" + name},
      {"services=" + GetDeviceUiKind(model_id)},
      {"id=" + cloud_->GetDeviceId()},
      {"mmid=" + model_id},
      {"flags=" + WifiSsidGenerator{cloud_, wifi_}.GenerateFlags()},
  };

  if (!cloud_->GetCloudId().empty())
    txt_record.emplace_back("gcd_id=" + cloud_->GetCloudId());

  if (!cloud_->GetDescription().empty())
    txt_record.emplace_back("note=" + cloud_->GetDescription());

  auto new_data = std::make_pair(port, txt_record);
  if (published_ == new_data)
    return;

  VLOG(1) << "Updating service using DNS-SD, port: " << port;
  published_ = new_data;
  dns_sd_->PublishService(kPrivetServiceType, port, txt_record);
}

void Publisher::RemoveService() {
  if (!published_.first)
    return;
  published_ = {};
  VLOG(1) << "Stopping service publishing";
  dns_sd_->StopPublishing(kPrivetServiceType);
}

}  // namespace privet
}  // namespace weave