1// Copyright 2015 The Weave Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "src/privet/publisher.h" 6 7#include <map> 8 9#include <weave/error.h> 10#include <weave/provider/dns_service_discovery.h> 11 12#include "src/privet/cloud_delegate.h" 13#include "src/privet/device_delegate.h" 14#include "src/privet/device_ui_kind.h" 15#include "src/privet/wifi_bootstrap_manager.h" 16#include "src/privet/wifi_ssid_generator.h" 17#include "src/string_utils.h" 18 19namespace weave { 20namespace privet { 21 22namespace { 23 24// The service type we'll expose via DNS-SD. 25const char kPrivetServiceType[] = "_privet._tcp"; 26 27} // namespace 28 29Publisher::Publisher(const DeviceDelegate* device, 30 const CloudDelegate* cloud, 31 const WifiDelegate* wifi, 32 provider::DnsServiceDiscovery* dns_sd) 33 : dns_sd_{dns_sd}, device_{device}, cloud_{cloud}, wifi_{wifi} { 34 CHECK(device_); 35 CHECK(cloud_); 36 CHECK(dns_sd_); 37 Update(); 38} 39 40Publisher::~Publisher() { 41 RemoveService(); 42} 43 44void Publisher::Update() { 45 if (device_->GetHttpEnpoint().first == 0) 46 return RemoveService(); 47 ExposeService(); 48} 49 50void Publisher::ExposeService() { 51 std::string name{cloud_->GetName()}; 52 std::string model_id{cloud_->GetModelId()}; 53 DCHECK_EQ(model_id.size(), 5U); 54 55 VLOG(2) << "DNS-SD update requested"; 56 const uint16_t port = device_->GetHttpEnpoint().first; 57 DCHECK_NE(port, 0); 58 59 std::vector<std::string> txt_record{ 60 {"txtvers=3"}, 61 {"ty=" + name}, 62 {"services=" + GetDeviceUiKind(model_id)}, 63 {"id=" + cloud_->GetDeviceId()}, 64 {"mmid=" + model_id}, 65 {"flags=" + WifiSsidGenerator{cloud_, wifi_}.GenerateFlags()}, 66 }; 67 68 if (!cloud_->GetCloudId().empty()) 69 txt_record.emplace_back("gcd_id=" + cloud_->GetCloudId()); 70 71 if (!cloud_->GetDescription().empty()) 72 txt_record.emplace_back("note=" + cloud_->GetDescription()); 73 74 auto new_data = std::make_pair(port, txt_record); 75 if (published_ == new_data) 76 return; 77 78 VLOG(1) << "Updating service using DNS-SD, port: " << port; 79 published_ = new_data; 80 dns_sd_->PublishService(kPrivetServiceType, port, txt_record); 81} 82 83void Publisher::RemoveService() { 84 if (!published_.first) 85 return; 86 published_ = {}; 87 VLOG(1) << "Stopping service publishing"; 88 dns_sd_->StopPublishing(kPrivetServiceType); 89} 90 91} // namespace privet 92} // namespace weave 93