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