android13/external/openscreen/osp/impl/dns_sd_publisher_client.cc

132 lines
4.1 KiB
C++

// Copyright 2021 The Chromium 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 "osp/impl/dns_sd_publisher_client.h"
#include <utility>
#include "discovery/common/config.h"
#include "discovery/dnssd/public/dns_sd_instance.h"
#include "discovery/dnssd/public/dns_sd_txt_record.h"
#include "discovery/public/dns_sd_service_factory.h"
#include "osp/public/service_info.h"
#include "platform/base/macros.h"
#include "util/osp_logging.h"
namespace openscreen {
namespace osp {
using State = ServicePublisher::State;
namespace {
constexpr char kFriendlyNameTxtKey[] = "fn";
constexpr char kDnsSdDomainId[] = "local";
discovery::DnsSdInstance ServiceConfigToDnsSdInstance(
const ServicePublisher::Config& config) {
discovery::DnsSdTxtRecord txt;
const bool did_set_everything =
txt.SetValue(kFriendlyNameTxtKey, config.friendly_name).ok();
OSP_DCHECK(did_set_everything);
// NOTE: Not totally clear how we should be using config.hostname, which in
// principle is already part of config.service_instance_name.
return discovery::DnsSdInstance(
config.service_instance_name, kOpenScreenServiceName, kDnsSdDomainId,
std::move(txt), config.connection_server_port);
}
} // namespace
DnsSdPublisherClient::DnsSdPublisherClient(ServicePublisher::Observer* observer,
openscreen::TaskRunner* task_runner)
: observer_(observer), task_runner_(task_runner) {
OSP_DCHECK(observer_);
OSP_DCHECK(task_runner_);
}
DnsSdPublisherClient::~DnsSdPublisherClient() = default;
void DnsSdPublisherClient::StartPublisher(
const ServicePublisher::Config& config) {
OSP_LOG_INFO << "StartPublisher with " << config.network_interfaces.size()
<< " interfaces";
StartPublisherInternal(config);
Error result = dns_sd_publisher_->Register(config);
if (result.ok()) {
SetState(State::kRunning);
} else {
OnFatalError(result);
SetState(State::kStopped);
}
}
void DnsSdPublisherClient::StartAndSuspendPublisher(
const ServicePublisher::Config& config) {
StartPublisherInternal(config);
SetState(State::kSuspended);
}
void DnsSdPublisherClient::StopPublisher() {
dns_sd_publisher_.reset();
SetState(State::kStopped);
}
void DnsSdPublisherClient::SuspendPublisher() {
OSP_DCHECK(dns_sd_publisher_);
dns_sd_publisher_->DeregisterAll();
SetState(State::kSuspended);
}
void DnsSdPublisherClient::ResumePublisher(
const ServicePublisher::Config& config) {
OSP_DCHECK(dns_sd_publisher_);
dns_sd_publisher_->Register(config);
SetState(State::kRunning);
}
void DnsSdPublisherClient::OnFatalError(Error error) {
observer_->OnError(error);
}
void DnsSdPublisherClient::OnRecoverableError(Error error) {
observer_->OnError(error);
}
void DnsSdPublisherClient::StartPublisherInternal(
const ServicePublisher::Config& config) {
OSP_DCHECK(!dns_sd_publisher_);
if (!dns_sd_service_) {
dns_sd_service_ = CreateDnsSdServiceInternal(config);
}
dns_sd_publisher_ = std::make_unique<OspDnsSdPublisher>(
dns_sd_service_.get(), kOpenScreenServiceName,
ServiceConfigToDnsSdInstance);
}
SerialDeletePtr<discovery::DnsSdService>
DnsSdPublisherClient::CreateDnsSdServiceInternal(
const ServicePublisher::Config& config) {
// NOTE: With the current API, the client cannot customize the behavior of
// DNS-SD beyond the interface list.
openscreen::discovery::Config dns_sd_config;
dns_sd_config.enable_querying = false;
dns_sd_config.network_info = config.network_interfaces;
// NOTE:
// It's desirable for the DNS-SD publisher and the DNS-SD listener for OSP to
// share the underlying mDNS socket and state, to avoid the agent from
// binding 2 sockets per network interface.
//
// This can be accomplished by having the agent use a shared instance of the
// discovery::DnsSdService, e.g. through a ref-counting handle, so that the
// OSP publisher and the OSP listener don't have to coordinate through an
// additional object.
return CreateDnsSdService(task_runner_, this, dns_sd_config);
}
} // namespace osp
} // namespace openscreen