xref: /aosp_15_r20/external/openscreen/discovery/dnssd/impl/service_dispatcher.cc (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #include "discovery/dnssd/impl/service_dispatcher.h"
6*3f982cf4SFabien Sanglard 
7*3f982cf4SFabien Sanglard #include <utility>
8*3f982cf4SFabien Sanglard 
9*3f982cf4SFabien Sanglard #include "discovery/common/config.h"
10*3f982cf4SFabien Sanglard #include "discovery/dnssd/impl/service_instance.h"
11*3f982cf4SFabien Sanglard #include "discovery/dnssd/public/dns_sd_instance.h"
12*3f982cf4SFabien Sanglard #include "discovery/mdns/public/mdns_service.h"
13*3f982cf4SFabien Sanglard #include "platform/api/serial_delete_ptr.h"
14*3f982cf4SFabien Sanglard #include "platform/api/task_runner.h"
15*3f982cf4SFabien Sanglard #include "util/trace_logging.h"
16*3f982cf4SFabien Sanglard 
17*3f982cf4SFabien Sanglard namespace openscreen {
18*3f982cf4SFabien Sanglard namespace discovery {
19*3f982cf4SFabien Sanglard namespace {
20*3f982cf4SFabien Sanglard 
ForAllQueriers(std::vector<std::unique_ptr<ServiceInstance>> * service_instances,std::function<void (DnsSdQuerier *)> action)21*3f982cf4SFabien Sanglard void ForAllQueriers(
22*3f982cf4SFabien Sanglard     std::vector<std::unique_ptr<ServiceInstance>>* service_instances,
23*3f982cf4SFabien Sanglard     std::function<void(DnsSdQuerier*)> action) {
24*3f982cf4SFabien Sanglard   for (auto& service_instance : *service_instances) {
25*3f982cf4SFabien Sanglard     auto* querier = service_instance->GetQuerier();
26*3f982cf4SFabien Sanglard     OSP_CHECK(querier);
27*3f982cf4SFabien Sanglard 
28*3f982cf4SFabien Sanglard     action(querier);
29*3f982cf4SFabien Sanglard   }
30*3f982cf4SFabien Sanglard }
31*3f982cf4SFabien Sanglard 
ForAllPublishers(std::vector<std::unique_ptr<ServiceInstance>> * service_instances,std::function<Error (DnsSdPublisher *)> action,const char * operation)32*3f982cf4SFabien Sanglard Error ForAllPublishers(
33*3f982cf4SFabien Sanglard     std::vector<std::unique_ptr<ServiceInstance>>* service_instances,
34*3f982cf4SFabien Sanglard     std::function<Error(DnsSdPublisher*)> action,
35*3f982cf4SFabien Sanglard     const char* operation) {
36*3f982cf4SFabien Sanglard   Error result = Error::None();
37*3f982cf4SFabien Sanglard   for (auto& service_instance : *service_instances) {
38*3f982cf4SFabien Sanglard     auto* publisher = service_instance->GetPublisher();
39*3f982cf4SFabien Sanglard     OSP_CHECK(publisher);
40*3f982cf4SFabien Sanglard 
41*3f982cf4SFabien Sanglard     TRACE_SCOPED(TraceCategory::kDiscovery, operation);
42*3f982cf4SFabien Sanglard     Error inner_result = action(publisher);
43*3f982cf4SFabien Sanglard     TRACE_SET_RESULT(inner_result);
44*3f982cf4SFabien Sanglard     if (!inner_result.ok()) {
45*3f982cf4SFabien Sanglard       result = std::move(inner_result);
46*3f982cf4SFabien Sanglard     }
47*3f982cf4SFabien Sanglard   }
48*3f982cf4SFabien Sanglard   return result;
49*3f982cf4SFabien Sanglard }
50*3f982cf4SFabien Sanglard 
51*3f982cf4SFabien Sanglard }  // namespace
52*3f982cf4SFabien Sanglard 
53*3f982cf4SFabien Sanglard // static
CreateDnsSdService(TaskRunner * task_runner,ReportingClient * reporting_client,const Config & config)54*3f982cf4SFabien Sanglard SerialDeletePtr<DnsSdService> CreateDnsSdService(
55*3f982cf4SFabien Sanglard     TaskRunner* task_runner,
56*3f982cf4SFabien Sanglard     ReportingClient* reporting_client,
57*3f982cf4SFabien Sanglard     const Config& config) {
58*3f982cf4SFabien Sanglard   return SerialDeletePtr<DnsSdService>(
59*3f982cf4SFabien Sanglard       task_runner,
60*3f982cf4SFabien Sanglard       new ServiceDispatcher(task_runner, reporting_client, config));
61*3f982cf4SFabien Sanglard }
62*3f982cf4SFabien Sanglard 
ServiceDispatcher(TaskRunner * task_runner,ReportingClient * reporting_client,const Config & config)63*3f982cf4SFabien Sanglard ServiceDispatcher::ServiceDispatcher(TaskRunner* task_runner,
64*3f982cf4SFabien Sanglard                                      ReportingClient* reporting_client,
65*3f982cf4SFabien Sanglard                                      const Config& config)
66*3f982cf4SFabien Sanglard     : task_runner_(task_runner),
67*3f982cf4SFabien Sanglard       publisher_(config.enable_publication ? this : nullptr),
68*3f982cf4SFabien Sanglard       querier_(config.enable_querying ? this : nullptr) {
69*3f982cf4SFabien Sanglard   OSP_DCHECK_GT(config.network_info.size(), 0);
70*3f982cf4SFabien Sanglard   OSP_DCHECK(task_runner);
71*3f982cf4SFabien Sanglard 
72*3f982cf4SFabien Sanglard   service_instances_.reserve(config.network_info.size());
73*3f982cf4SFabien Sanglard   for (const auto& network_info : config.network_info) {
74*3f982cf4SFabien Sanglard     service_instances_.push_back(std::make_unique<ServiceInstance>(
75*3f982cf4SFabien Sanglard         task_runner_, reporting_client, config, network_info));
76*3f982cf4SFabien Sanglard   }
77*3f982cf4SFabien Sanglard }
78*3f982cf4SFabien Sanglard 
~ServiceDispatcher()79*3f982cf4SFabien Sanglard ServiceDispatcher::~ServiceDispatcher() {
80*3f982cf4SFabien Sanglard   OSP_DCHECK(task_runner_->IsRunningOnTaskRunner());
81*3f982cf4SFabien Sanglard }
82*3f982cf4SFabien Sanglard 
83*3f982cf4SFabien Sanglard // DnsSdQuerier overrides.
StartQuery(const std::string & service,Callback * cb)84*3f982cf4SFabien Sanglard void ServiceDispatcher::StartQuery(const std::string& service, Callback* cb) {
85*3f982cf4SFabien Sanglard   TRACE_DEFAULT_SCOPED(TraceCategory::kDiscovery);
86*3f982cf4SFabien Sanglard   auto start_query = [&service, cb](DnsSdQuerier* querier) {
87*3f982cf4SFabien Sanglard     querier->StartQuery(service, cb);
88*3f982cf4SFabien Sanglard   };
89*3f982cf4SFabien Sanglard   ForAllQueriers(&service_instances_, std::move(start_query));
90*3f982cf4SFabien Sanglard }
91*3f982cf4SFabien Sanglard 
StopQuery(const std::string & service,Callback * cb)92*3f982cf4SFabien Sanglard void ServiceDispatcher::StopQuery(const std::string& service, Callback* cb) {
93*3f982cf4SFabien Sanglard   TRACE_DEFAULT_SCOPED(TraceCategory::kDiscovery);
94*3f982cf4SFabien Sanglard   auto stop_query = [&service, cb](DnsSdQuerier* querier) {
95*3f982cf4SFabien Sanglard     querier->StopQuery(service, cb);
96*3f982cf4SFabien Sanglard   };
97*3f982cf4SFabien Sanglard   ForAllQueriers(&service_instances_, std::move(stop_query));
98*3f982cf4SFabien Sanglard }
99*3f982cf4SFabien Sanglard 
ReinitializeQueries(const std::string & service)100*3f982cf4SFabien Sanglard void ServiceDispatcher::ReinitializeQueries(const std::string& service) {
101*3f982cf4SFabien Sanglard   TRACE_DEFAULT_SCOPED(TraceCategory::kDiscovery);
102*3f982cf4SFabien Sanglard   auto reinitialize_queries = [&service](DnsSdQuerier* querier) {
103*3f982cf4SFabien Sanglard     querier->ReinitializeQueries(service);
104*3f982cf4SFabien Sanglard   };
105*3f982cf4SFabien Sanglard   ForAllQueriers(&service_instances_, std::move(reinitialize_queries));
106*3f982cf4SFabien Sanglard }
107*3f982cf4SFabien Sanglard 
108*3f982cf4SFabien Sanglard // DnsSdPublisher overrides.
Register(const DnsSdInstance & instance,Client * client)109*3f982cf4SFabien Sanglard Error ServiceDispatcher::Register(const DnsSdInstance& instance,
110*3f982cf4SFabien Sanglard                                   Client* client) {
111*3f982cf4SFabien Sanglard   TRACE_DEFAULT_SCOPED(TraceCategory::kDiscovery);
112*3f982cf4SFabien Sanglard   auto register_instance = [&instance, client](DnsSdPublisher* publisher) {
113*3f982cf4SFabien Sanglard     return publisher->Register(instance, client);
114*3f982cf4SFabien Sanglard   };
115*3f982cf4SFabien Sanglard   return ForAllPublishers(&service_instances_, std::move(register_instance),
116*3f982cf4SFabien Sanglard                           "DNS-SD.Register");
117*3f982cf4SFabien Sanglard }
118*3f982cf4SFabien Sanglard 
UpdateRegistration(const DnsSdInstance & instance)119*3f982cf4SFabien Sanglard Error ServiceDispatcher::UpdateRegistration(const DnsSdInstance& instance) {
120*3f982cf4SFabien Sanglard   TRACE_DEFAULT_SCOPED(TraceCategory::kDiscovery);
121*3f982cf4SFabien Sanglard   auto update_registration = [&instance](DnsSdPublisher* publisher) {
122*3f982cf4SFabien Sanglard     return publisher->UpdateRegistration(instance);
123*3f982cf4SFabien Sanglard   };
124*3f982cf4SFabien Sanglard   return ForAllPublishers(&service_instances_, std::move(update_registration),
125*3f982cf4SFabien Sanglard                           "DNS-SD.UpdateRegistration");
126*3f982cf4SFabien Sanglard }
127*3f982cf4SFabien Sanglard 
DeregisterAll(const std::string & service)128*3f982cf4SFabien Sanglard ErrorOr<int> ServiceDispatcher::DeregisterAll(const std::string& service) {
129*3f982cf4SFabien Sanglard   TRACE_DEFAULT_SCOPED(TraceCategory::kDiscovery);
130*3f982cf4SFabien Sanglard   int total = 0;
131*3f982cf4SFabien Sanglard   Error failure = Error::None();
132*3f982cf4SFabien Sanglard   for (auto& service_instance : service_instances_) {
133*3f982cf4SFabien Sanglard     auto* publisher = service_instance->GetPublisher();
134*3f982cf4SFabien Sanglard     OSP_CHECK(publisher);
135*3f982cf4SFabien Sanglard 
136*3f982cf4SFabien Sanglard     TRACE_SCOPED(TraceCategory::kDiscovery, "DNS-SD.DeregisterAll");
137*3f982cf4SFabien Sanglard     auto result = publisher->DeregisterAll(service);
138*3f982cf4SFabien Sanglard     if (result.is_error()) {
139*3f982cf4SFabien Sanglard       TRACE_SET_RESULT(result.error());
140*3f982cf4SFabien Sanglard       failure = std::move(result.error());
141*3f982cf4SFabien Sanglard     } else {
142*3f982cf4SFabien Sanglard       total += result.value();
143*3f982cf4SFabien Sanglard     }
144*3f982cf4SFabien Sanglard   }
145*3f982cf4SFabien Sanglard 
146*3f982cf4SFabien Sanglard   if (!failure.ok()) {
147*3f982cf4SFabien Sanglard     return failure;
148*3f982cf4SFabien Sanglard   } else {
149*3f982cf4SFabien Sanglard     return total;
150*3f982cf4SFabien Sanglard   }
151*3f982cf4SFabien Sanglard }
152*3f982cf4SFabien Sanglard 
153*3f982cf4SFabien Sanglard }  // namespace discovery
154*3f982cf4SFabien Sanglard }  // namespace openscreen
155