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