| // 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 |