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