1 // Copyright 2020 The Chromium 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 #ifndef DISCOVERY_PUBLIC_DNS_SD_SERVICE_PUBLISHER_H_ 6 #define DISCOVERY_PUBLIC_DNS_SD_SERVICE_PUBLISHER_H_ 7 8 #include <string> 9 #include <utility> 10 11 #include "discovery/dnssd/public/dns_sd_instance.h" 12 #include "discovery/dnssd/public/dns_sd_instance_endpoint.h" 13 #include "discovery/dnssd/public/dns_sd_publisher.h" 14 #include "discovery/dnssd/public/dns_sd_service.h" 15 #include "platform/base/error.h" 16 #include "util/osp_logging.h" 17 18 namespace openscreen { 19 namespace discovery { 20 21 // This class represents a top-level discovery API which sits on top of DNS-SD. 22 // The main purpose of this class is to hide DNS-SD internals from embedders who 23 // do not care about the specific functionality and do not need to understand 24 // DNS-SD Internals. 25 // T is the service-specific type which stores information regarding a specific 26 // service instance. 27 // NOTE: This class is not thread-safe and calls will be made to DnsSdService in 28 // the same sequence and on the same threads from which these methods are 29 // called. This is to avoid forcing design decisions on embedders who write 30 // their own implementations of the DNS-SD layer. 31 template <typename T> 32 class DnsSdServicePublisher : public DnsSdPublisher::Client { 33 public: 34 // This function type is responsible for converting from a T type to a 35 // DNS service instance (to publish to the network). 36 using ServiceInstanceConverter = std::function<DnsSdInstance(const T&)>; 37 DnsSdServicePublisher(DnsSdService * service,std::string service_name,ServiceInstanceConverter conversion)38 DnsSdServicePublisher(DnsSdService* service, 39 std::string service_name, 40 ServiceInstanceConverter conversion) 41 : conversion_(conversion), 42 service_name_(std::move(service_name)), 43 publisher_(service ? service->GetPublisher() : nullptr) { 44 OSP_DCHECK(publisher_); 45 } 46 47 ~DnsSdServicePublisher() = default; 48 Register(const T & service)49 Error Register(const T& service) { 50 if (!service.IsValid()) { 51 return Error::Code::kParameterInvalid; 52 } 53 54 DnsSdInstance instance = conversion_(service); 55 return publisher_->Register(instance, this); 56 } 57 UpdateRegistration(const T & service)58 Error UpdateRegistration(const T& service) { 59 if (!service.IsValid()) { 60 return Error::Code::kParameterInvalid; 61 } 62 63 DnsSdInstance instance = conversion_(service); 64 return publisher_->UpdateRegistration(instance); 65 } 66 DeregisterAll()67 ErrorOr<int> DeregisterAll() { 68 return publisher_->DeregisterAll(service_name_); 69 } 70 71 protected: 72 // DnsSdPublisher::Client overrides. 73 // 74 // Embedders who care about the instance id with which the service was 75 // published may override this method. OnEndpointClaimed(const DnsSdInstance & requested_instance,const DnsSdInstanceEndpoint & claimed_endpoint)76 void OnEndpointClaimed( 77 const DnsSdInstance& requested_instance, 78 const DnsSdInstanceEndpoint& claimed_endpoint) override { 79 OSP_DVLOG << "Instance ID '" << claimed_endpoint.instance_id() 80 << "' claimed for requested ID '" 81 << requested_instance.instance_id() << "'"; 82 OnInstanceClaimed(requested_instance.instance_id()); 83 } 84 OnInstanceClaimed(const std::string & requested_instance_id)85 virtual void OnInstanceClaimed(const std::string& requested_instance_id) {} 86 87 private: 88 ServiceInstanceConverter conversion_; 89 std::string service_name_; 90 DnsSdPublisher* const publisher_; 91 }; 92 93 } // namespace discovery 94 } // namespace openscreen 95 96 #endif // DISCOVERY_PUBLIC_DNS_SD_SERVICE_PUBLISHER_H_ 97