Home | History | Annotate | Download | only in privet
      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 
     19 namespace weave {
     20 namespace privet {
     21 
     22 namespace {
     23 
     24 // The service type we'll expose via DNS-SD.
     25 const char kPrivetServiceType[] = "_privet._tcp";
     26 
     27 }  // namespace
     28 
     29 Publisher::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 
     40 Publisher::~Publisher() {
     41   RemoveService();
     42 }
     43 
     44 void Publisher::Update() {
     45   if (device_->GetHttpEnpoint().first == 0)
     46     return RemoveService();
     47   ExposeService();
     48 }
     49 
     50 void 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 
     83 void 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