// Copyright 2020 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. #ifndef DISCOVERY_PUBLIC_DNS_SD_SERVICE_PUBLISHER_H_ #define DISCOVERY_PUBLIC_DNS_SD_SERVICE_PUBLISHER_H_ #include #include #include "discovery/dnssd/public/dns_sd_instance.h" #include "discovery/dnssd/public/dns_sd_instance_endpoint.h" #include "discovery/dnssd/public/dns_sd_publisher.h" #include "discovery/dnssd/public/dns_sd_service.h" #include "platform/base/error.h" #include "util/osp_logging.h" namespace openscreen { namespace discovery { // This class represents a top-level discovery API which sits on top of DNS-SD. // The main purpose of this class is to hide DNS-SD internals from embedders who // do not care about the specific functionality and do not need to understand // DNS-SD Internals. // T is the service-specific type which stores information regarding a specific // service instance. // NOTE: This class is not thread-safe and calls will be made to DnsSdService in // the same sequence and on the same threads from which these methods are // called. This is to avoid forcing design decisions on embedders who write // their own implementations of the DNS-SD layer. template class DnsSdServicePublisher : public DnsSdPublisher::Client { public: // This function type is responsible for converting from a T type to a // DNS service instance (to publish to the network). using ServiceInstanceConverter = std::function; DnsSdServicePublisher(DnsSdService* service, std::string service_name, ServiceInstanceConverter conversion) : conversion_(conversion), service_name_(std::move(service_name)), publisher_(service ? service->GetPublisher() : nullptr) { OSP_DCHECK(publisher_); } ~DnsSdServicePublisher() = default; Error Register(const T& service) { if (!service.IsValid()) { return Error::Code::kParameterInvalid; } DnsSdInstance instance = conversion_(service); return publisher_->Register(instance, this); } Error UpdateRegistration(const T& service) { if (!service.IsValid()) { return Error::Code::kParameterInvalid; } DnsSdInstance instance = conversion_(service); return publisher_->UpdateRegistration(instance); } ErrorOr DeregisterAll() { return publisher_->DeregisterAll(service_name_); } protected: // DnsSdPublisher::Client overrides. // // Embedders who care about the instance id with which the service was // published may override this method. void OnEndpointClaimed( const DnsSdInstance& requested_instance, const DnsSdInstanceEndpoint& claimed_endpoint) override { OSP_DVLOG << "Instance ID '" << claimed_endpoint.instance_id() << "' claimed for requested ID '" << requested_instance.instance_id() << "'"; OnInstanceClaimed(requested_instance.instance_id()); } virtual void OnInstanceClaimed(const std::string& requested_instance_id) {} private: ServiceInstanceConverter conversion_; std::string service_name_; DnsSdPublisher* const publisher_; }; } // namespace discovery } // namespace openscreen #endif // DISCOVERY_PUBLIC_DNS_SD_SERVICE_PUBLISHER_H_