1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker * Copyright (c) 2024, The OpenThread Authors.
3*4a64e381SAndroid Build Coastguard Worker * All rights reserved.
4*4a64e381SAndroid Build Coastguard Worker *
5*4a64e381SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*4a64e381SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*4a64e381SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
8*4a64e381SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
9*4a64e381SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
10*4a64e381SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
11*4a64e381SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
12*4a64e381SAndroid Build Coastguard Worker * 3. Neither the name of the copyright holder nor the
13*4a64e381SAndroid Build Coastguard Worker * names of its contributors may be used to endorse or promote products
14*4a64e381SAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
15*4a64e381SAndroid Build Coastguard Worker *
16*4a64e381SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*4a64e381SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*4a64e381SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*4a64e381SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*4a64e381SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*4a64e381SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*4a64e381SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*4a64e381SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*4a64e381SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*4a64e381SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*4a64e381SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
27*4a64e381SAndroid Build Coastguard Worker */
28*4a64e381SAndroid Build Coastguard Worker
29*4a64e381SAndroid Build Coastguard Worker #define OTBR_LOG_TAG "MDNS"
30*4a64e381SAndroid Build Coastguard Worker
31*4a64e381SAndroid Build Coastguard Worker #include "android/mdns_publisher.hpp"
32*4a64e381SAndroid Build Coastguard Worker
33*4a64e381SAndroid Build Coastguard Worker namespace otbr {
34*4a64e381SAndroid Build Coastguard Worker
Create(Mdns::Publisher::StateCallback aCallback)35*4a64e381SAndroid Build Coastguard Worker Mdns::Publisher *Mdns::Publisher::Create(Mdns::Publisher::StateCallback aCallback)
36*4a64e381SAndroid Build Coastguard Worker {
37*4a64e381SAndroid Build Coastguard Worker return new Android::MdnsPublisher(std::move(aCallback));
38*4a64e381SAndroid Build Coastguard Worker }
39*4a64e381SAndroid Build Coastguard Worker
40*4a64e381SAndroid Build Coastguard Worker namespace Android {
DnsErrorToOtbrErrorImpl(int32_t aError)41*4a64e381SAndroid Build Coastguard Worker otbrError DnsErrorToOtbrErrorImpl(int32_t aError)
42*4a64e381SAndroid Build Coastguard Worker {
43*4a64e381SAndroid Build Coastguard Worker return aError == 0 ? OTBR_ERROR_NONE : OTBR_ERROR_MDNS;
44*4a64e381SAndroid Build Coastguard Worker }
45*4a64e381SAndroid Build Coastguard Worker
DnsErrorToOtbrError(int32_t aError)46*4a64e381SAndroid Build Coastguard Worker otbrError MdnsPublisher::DnsErrorToOtbrError(int32_t aError)
47*4a64e381SAndroid Build Coastguard Worker {
48*4a64e381SAndroid Build Coastguard Worker return DnsErrorToOtbrErrorImpl(aError);
49*4a64e381SAndroid Build Coastguard Worker }
50*4a64e381SAndroid Build Coastguard Worker
onSuccess()51*4a64e381SAndroid Build Coastguard Worker Status MdnsPublisher::NsdStatusReceiver::onSuccess()
52*4a64e381SAndroid Build Coastguard Worker {
53*4a64e381SAndroid Build Coastguard Worker if (!mCallback.IsNull())
54*4a64e381SAndroid Build Coastguard Worker {
55*4a64e381SAndroid Build Coastguard Worker std::move(mCallback)(OTBR_ERROR_NONE);
56*4a64e381SAndroid Build Coastguard Worker }
57*4a64e381SAndroid Build Coastguard Worker
58*4a64e381SAndroid Build Coastguard Worker return Status::ok();
59*4a64e381SAndroid Build Coastguard Worker }
60*4a64e381SAndroid Build Coastguard Worker
onServiceDiscovered(const std::string & aName,const std::string & aType,bool aIsFound)61*4a64e381SAndroid Build Coastguard Worker Status MdnsPublisher::NsdDiscoverServiceCallback::onServiceDiscovered(const std::string &aName,
62*4a64e381SAndroid Build Coastguard Worker const std::string &aType,
63*4a64e381SAndroid Build Coastguard Worker bool aIsFound)
64*4a64e381SAndroid Build Coastguard Worker {
65*4a64e381SAndroid Build Coastguard Worker std::shared_ptr<ServiceSubscription> subscription = mSubscription.lock();
66*4a64e381SAndroid Build Coastguard Worker
67*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(subscription != nullptr);
68*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aIsFound, subscription->mPublisher.OnServiceRemoved(0, aType, aName));
69*4a64e381SAndroid Build Coastguard Worker
70*4a64e381SAndroid Build Coastguard Worker subscription->Resolve(aName, aType);
71*4a64e381SAndroid Build Coastguard Worker
72*4a64e381SAndroid Build Coastguard Worker exit:
73*4a64e381SAndroid Build Coastguard Worker return Status::ok();
74*4a64e381SAndroid Build Coastguard Worker }
75*4a64e381SAndroid Build Coastguard Worker
onServiceResolved(const std::string & aHostname,int aNetifIndex,const std::string & aName,const std::string & aType,int aPort,const std::vector<std::string> & aAddresses,const std::vector<DnsTxtAttribute> & aTxt,int aTtlSeconds)76*4a64e381SAndroid Build Coastguard Worker Status MdnsPublisher::NsdResolveServiceCallback::onServiceResolved(const std::string &aHostname,
77*4a64e381SAndroid Build Coastguard Worker int aNetifIndex,
78*4a64e381SAndroid Build Coastguard Worker const std::string &aName,
79*4a64e381SAndroid Build Coastguard Worker const std::string &aType,
80*4a64e381SAndroid Build Coastguard Worker int aPort,
81*4a64e381SAndroid Build Coastguard Worker const std::vector<std::string> &aAddresses,
82*4a64e381SAndroid Build Coastguard Worker const std::vector<DnsTxtAttribute> &aTxt,
83*4a64e381SAndroid Build Coastguard Worker int aTtlSeconds)
84*4a64e381SAndroid Build Coastguard Worker {
85*4a64e381SAndroid Build Coastguard Worker DiscoveredInstanceInfo info;
86*4a64e381SAndroid Build Coastguard Worker TxtList txtList;
87*4a64e381SAndroid Build Coastguard Worker std::shared_ptr<ServiceSubscription> subscription = mSubscription.lock();
88*4a64e381SAndroid Build Coastguard Worker
89*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(subscription != nullptr);
90*4a64e381SAndroid Build Coastguard Worker
91*4a64e381SAndroid Build Coastguard Worker info.mHostName = aHostname + ".local.";
92*4a64e381SAndroid Build Coastguard Worker info.mName = aName;
93*4a64e381SAndroid Build Coastguard Worker info.mPort = aPort;
94*4a64e381SAndroid Build Coastguard Worker info.mTtl = std::clamp(aTtlSeconds, kMinResolvedTtl, kMaxResolvedTtl);
95*4a64e381SAndroid Build Coastguard Worker info.mNetifIndex = aNetifIndex;
96*4a64e381SAndroid Build Coastguard Worker for (const auto &addressStr : aAddresses)
97*4a64e381SAndroid Build Coastguard Worker {
98*4a64e381SAndroid Build Coastguard Worker Ip6Address address;
99*4a64e381SAndroid Build Coastguard Worker // addressStr may be in the format of "fe80::1234%eth0"
100*4a64e381SAndroid Build Coastguard Worker std::string addrStr(addressStr.begin(), std::find(addressStr.begin(), addressStr.end(), '%'));
101*4a64e381SAndroid Build Coastguard Worker int error = Ip6Address::FromString(addrStr.c_str(), address);
102*4a64e381SAndroid Build Coastguard Worker
103*4a64e381SAndroid Build Coastguard Worker if (error != OTBR_ERROR_NONE)
104*4a64e381SAndroid Build Coastguard Worker {
105*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Failed to parse resolved IPv6 address: %s", addressStr.c_str());
106*4a64e381SAndroid Build Coastguard Worker continue;
107*4a64e381SAndroid Build Coastguard Worker }
108*4a64e381SAndroid Build Coastguard Worker info.mAddresses.push_back(address);
109*4a64e381SAndroid Build Coastguard Worker }
110*4a64e381SAndroid Build Coastguard Worker for (const auto &entry : aTxt)
111*4a64e381SAndroid Build Coastguard Worker {
112*4a64e381SAndroid Build Coastguard Worker txtList.emplace_back(entry.name.c_str(), entry.value.data(), entry.value.size());
113*4a64e381SAndroid Build Coastguard Worker }
114*4a64e381SAndroid Build Coastguard Worker EncodeTxtData(txtList, info.mTxtData);
115*4a64e381SAndroid Build Coastguard Worker
116*4a64e381SAndroid Build Coastguard Worker subscription->mPublisher.OnServiceResolved(aType, info);
117*4a64e381SAndroid Build Coastguard Worker
118*4a64e381SAndroid Build Coastguard Worker exit:
119*4a64e381SAndroid Build Coastguard Worker return Status::ok();
120*4a64e381SAndroid Build Coastguard Worker }
121*4a64e381SAndroid Build Coastguard Worker
onHostResolved(const std::string & aName,const std::vector<std::string> & aAddresses)122*4a64e381SAndroid Build Coastguard Worker Status MdnsPublisher::NsdResolveHostCallback::onHostResolved(const std::string &aName,
123*4a64e381SAndroid Build Coastguard Worker const std::vector<std::string> &aAddresses)
124*4a64e381SAndroid Build Coastguard Worker {
125*4a64e381SAndroid Build Coastguard Worker DiscoveredHostInfo info;
126*4a64e381SAndroid Build Coastguard Worker std::shared_ptr<HostSubscription> subscription = mSubscription.lock();
127*4a64e381SAndroid Build Coastguard Worker
128*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(subscription != nullptr);
129*4a64e381SAndroid Build Coastguard Worker
130*4a64e381SAndroid Build Coastguard Worker info.mTtl = kDefaultResolvedTtl;
131*4a64e381SAndroid Build Coastguard Worker for (const auto &addressStr : aAddresses)
132*4a64e381SAndroid Build Coastguard Worker {
133*4a64e381SAndroid Build Coastguard Worker Ip6Address address;
134*4a64e381SAndroid Build Coastguard Worker int error = Ip6Address::FromString(addressStr.c_str(), address);
135*4a64e381SAndroid Build Coastguard Worker
136*4a64e381SAndroid Build Coastguard Worker if (error != OTBR_ERROR_NONE)
137*4a64e381SAndroid Build Coastguard Worker {
138*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Failed to parse resolved IPv6 address: %s", addressStr.c_str());
139*4a64e381SAndroid Build Coastguard Worker continue;
140*4a64e381SAndroid Build Coastguard Worker }
141*4a64e381SAndroid Build Coastguard Worker info.mAddresses.push_back(address);
142*4a64e381SAndroid Build Coastguard Worker }
143*4a64e381SAndroid Build Coastguard Worker
144*4a64e381SAndroid Build Coastguard Worker subscription->mPublisher.OnHostResolved(aName, info);
145*4a64e381SAndroid Build Coastguard Worker
146*4a64e381SAndroid Build Coastguard Worker exit:
147*4a64e381SAndroid Build Coastguard Worker return Status::ok();
148*4a64e381SAndroid Build Coastguard Worker }
149*4a64e381SAndroid Build Coastguard Worker
SetINsdPublisher(std::shared_ptr<INsdPublisher> aINsdPublisher)150*4a64e381SAndroid Build Coastguard Worker void MdnsPublisher::SetINsdPublisher(std::shared_ptr<INsdPublisher> aINsdPublisher)
151*4a64e381SAndroid Build Coastguard Worker {
152*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Set INsdPublisher %p", aINsdPublisher.get());
153*4a64e381SAndroid Build Coastguard Worker
154*4a64e381SAndroid Build Coastguard Worker mNsdPublisher = std::move(aINsdPublisher);
155*4a64e381SAndroid Build Coastguard Worker
156*4a64e381SAndroid Build Coastguard Worker if (mNsdPublisher != nullptr)
157*4a64e381SAndroid Build Coastguard Worker {
158*4a64e381SAndroid Build Coastguard Worker mStateCallback(Mdns::Publisher::State::kReady);
159*4a64e381SAndroid Build Coastguard Worker }
160*4a64e381SAndroid Build Coastguard Worker else
161*4a64e381SAndroid Build Coastguard Worker {
162*4a64e381SAndroid Build Coastguard Worker mStateCallback(Mdns::Publisher::State::kIdle);
163*4a64e381SAndroid Build Coastguard Worker }
164*4a64e381SAndroid Build Coastguard Worker }
165*4a64e381SAndroid Build Coastguard Worker
onError(int aError)166*4a64e381SAndroid Build Coastguard Worker Status MdnsPublisher::NsdStatusReceiver::onError(int aError)
167*4a64e381SAndroid Build Coastguard Worker {
168*4a64e381SAndroid Build Coastguard Worker if (!mCallback.IsNull())
169*4a64e381SAndroid Build Coastguard Worker {
170*4a64e381SAndroid Build Coastguard Worker std::move(mCallback)(DnsErrorToOtbrErrorImpl(aError));
171*4a64e381SAndroid Build Coastguard Worker }
172*4a64e381SAndroid Build Coastguard Worker
173*4a64e381SAndroid Build Coastguard Worker return Status::ok();
174*4a64e381SAndroid Build Coastguard Worker }
175*4a64e381SAndroid Build Coastguard Worker
CreateReceiver(Mdns::Publisher::ResultCallback aCallback)176*4a64e381SAndroid Build Coastguard Worker std::shared_ptr<MdnsPublisher::NsdStatusReceiver> CreateReceiver(Mdns::Publisher::ResultCallback aCallback)
177*4a64e381SAndroid Build Coastguard Worker {
178*4a64e381SAndroid Build Coastguard Worker return ndk::SharedRefBase::make<MdnsPublisher::NsdStatusReceiver>(std::move(aCallback));
179*4a64e381SAndroid Build Coastguard Worker }
180*4a64e381SAndroid Build Coastguard Worker
CreateNsdDiscoverServiceCallback(const std::shared_ptr<MdnsPublisher::ServiceSubscription> & aServiceSubscription)181*4a64e381SAndroid Build Coastguard Worker std::shared_ptr<MdnsPublisher::NsdDiscoverServiceCallback> CreateNsdDiscoverServiceCallback(
182*4a64e381SAndroid Build Coastguard Worker const std::shared_ptr<MdnsPublisher::ServiceSubscription> &aServiceSubscription)
183*4a64e381SAndroid Build Coastguard Worker {
184*4a64e381SAndroid Build Coastguard Worker return ndk::SharedRefBase::make<MdnsPublisher::NsdDiscoverServiceCallback>(aServiceSubscription);
185*4a64e381SAndroid Build Coastguard Worker }
186*4a64e381SAndroid Build Coastguard Worker
CreateNsdResolveServiceCallback(const std::shared_ptr<MdnsPublisher::ServiceSubscription> & aServiceSubscription)187*4a64e381SAndroid Build Coastguard Worker std::shared_ptr<MdnsPublisher::NsdResolveServiceCallback> CreateNsdResolveServiceCallback(
188*4a64e381SAndroid Build Coastguard Worker const std::shared_ptr<MdnsPublisher::ServiceSubscription> &aServiceSubscription)
189*4a64e381SAndroid Build Coastguard Worker {
190*4a64e381SAndroid Build Coastguard Worker return ndk::SharedRefBase::make<MdnsPublisher::NsdResolveServiceCallback>(aServiceSubscription);
191*4a64e381SAndroid Build Coastguard Worker }
192*4a64e381SAndroid Build Coastguard Worker
CreateNsdResolveHostCallback(const std::shared_ptr<MdnsPublisher::HostSubscription> & aHostSubscription)193*4a64e381SAndroid Build Coastguard Worker std::shared_ptr<MdnsPublisher::NsdResolveHostCallback> CreateNsdResolveHostCallback(
194*4a64e381SAndroid Build Coastguard Worker const std::shared_ptr<MdnsPublisher::HostSubscription> &aHostSubscription)
195*4a64e381SAndroid Build Coastguard Worker {
196*4a64e381SAndroid Build Coastguard Worker return ndk::SharedRefBase::make<MdnsPublisher::NsdResolveHostCallback>(aHostSubscription);
197*4a64e381SAndroid Build Coastguard Worker }
198*4a64e381SAndroid Build Coastguard Worker
DieForNotImplemented(const char * aFuncName)199*4a64e381SAndroid Build Coastguard Worker void DieForNotImplemented(const char *aFuncName)
200*4a64e381SAndroid Build Coastguard Worker {
201*4a64e381SAndroid Build Coastguard Worker VerifyOrDie(false, (std::string(aFuncName) + " is not implemented").c_str());
202*4a64e381SAndroid Build Coastguard Worker }
203*4a64e381SAndroid Build Coastguard Worker
PublishServiceImpl(const std::string & aHostName,const std::string & aName,const std::string & aType,const SubTypeList & aSubTypeList,uint16_t aPort,const TxtData & aTxtData,ResultCallback && aCallback)204*4a64e381SAndroid Build Coastguard Worker otbrError MdnsPublisher::PublishServiceImpl(const std::string &aHostName,
205*4a64e381SAndroid Build Coastguard Worker const std::string &aName,
206*4a64e381SAndroid Build Coastguard Worker const std::string &aType,
207*4a64e381SAndroid Build Coastguard Worker const SubTypeList &aSubTypeList,
208*4a64e381SAndroid Build Coastguard Worker uint16_t aPort,
209*4a64e381SAndroid Build Coastguard Worker const TxtData &aTxtData,
210*4a64e381SAndroid Build Coastguard Worker ResultCallback &&aCallback)
211*4a64e381SAndroid Build Coastguard Worker {
212*4a64e381SAndroid Build Coastguard Worker int32_t listenerId = AllocateListenerId();
213*4a64e381SAndroid Build Coastguard Worker TxtList txtList;
214*4a64e381SAndroid Build Coastguard Worker otbrError error = OTBR_ERROR_NONE;
215*4a64e381SAndroid Build Coastguard Worker
216*4a64e381SAndroid Build Coastguard Worker std::vector<DnsTxtAttribute> txtAttributes;
217*4a64e381SAndroid Build Coastguard Worker
218*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(IsStarted(), error = OTBR_ERROR_MDNS);
219*4a64e381SAndroid Build Coastguard Worker if (mNsdPublisher == nullptr)
220*4a64e381SAndroid Build Coastguard Worker {
221*4a64e381SAndroid Build Coastguard Worker otbrLogWarning("No platform mDNS implementation registered!");
222*4a64e381SAndroid Build Coastguard Worker ExitNow(error = OTBR_ERROR_MDNS);
223*4a64e381SAndroid Build Coastguard Worker }
224*4a64e381SAndroid Build Coastguard Worker
225*4a64e381SAndroid Build Coastguard Worker aCallback = HandleDuplicateServiceRegistration(aHostName, aName, aType, aSubTypeList, aPort, aTxtData,
226*4a64e381SAndroid Build Coastguard Worker std::move(aCallback));
227*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(!aCallback.IsNull(), error = OTBR_ERROR_INVALID_STATE);
228*4a64e381SAndroid Build Coastguard Worker
229*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = DecodeTxtData(txtList, aTxtData.data(), aTxtData.size()));
230*4a64e381SAndroid Build Coastguard Worker
231*4a64e381SAndroid Build Coastguard Worker for (const auto &txtEntry : txtList)
232*4a64e381SAndroid Build Coastguard Worker {
233*4a64e381SAndroid Build Coastguard Worker DnsTxtAttribute txtAttribute;
234*4a64e381SAndroid Build Coastguard Worker
235*4a64e381SAndroid Build Coastguard Worker txtAttribute.name = txtEntry.mKey;
236*4a64e381SAndroid Build Coastguard Worker txtAttribute.value = txtEntry.mValue;
237*4a64e381SAndroid Build Coastguard Worker txtAttributes.push_back(std::move(txtAttribute));
238*4a64e381SAndroid Build Coastguard Worker }
239*4a64e381SAndroid Build Coastguard Worker AddServiceRegistration(MakeUnique<NsdServiceRegistration>(aHostName, aName, aType, aSubTypeList, aPort, aTxtData,
240*4a64e381SAndroid Build Coastguard Worker /* aCallback= */ nullptr, this, listenerId,
241*4a64e381SAndroid Build Coastguard Worker mNsdPublisher));
242*4a64e381SAndroid Build Coastguard Worker
243*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Publishing service %s.%s listener ID = %d", aName.c_str(), aType.c_str(), listenerId);
244*4a64e381SAndroid Build Coastguard Worker
245*4a64e381SAndroid Build Coastguard Worker mNsdPublisher->registerService(aHostName, aName, aType, aSubTypeList, aPort, txtAttributes,
246*4a64e381SAndroid Build Coastguard Worker CreateReceiver(std::move(aCallback)), listenerId);
247*4a64e381SAndroid Build Coastguard Worker
248*4a64e381SAndroid Build Coastguard Worker exit:
249*4a64e381SAndroid Build Coastguard Worker return error;
250*4a64e381SAndroid Build Coastguard Worker }
251*4a64e381SAndroid Build Coastguard Worker
UnpublishService(const std::string & aName,const std::string & aType,ResultCallback && aCallback)252*4a64e381SAndroid Build Coastguard Worker void MdnsPublisher::UnpublishService(const std::string &aName, const std::string &aType, ResultCallback &&aCallback)
253*4a64e381SAndroid Build Coastguard Worker {
254*4a64e381SAndroid Build Coastguard Worker NsdServiceRegistration *serviceRegistration =
255*4a64e381SAndroid Build Coastguard Worker static_cast<NsdServiceRegistration *>(FindServiceRegistration(aName, aType));
256*4a64e381SAndroid Build Coastguard Worker
257*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(IsStarted(), std::move(aCallback)(OTBR_ERROR_MDNS));
258*4a64e381SAndroid Build Coastguard Worker if (mNsdPublisher == nullptr)
259*4a64e381SAndroid Build Coastguard Worker {
260*4a64e381SAndroid Build Coastguard Worker otbrLogWarning("No platform mDNS implementation registered!");
261*4a64e381SAndroid Build Coastguard Worker ExitNow(std::move(aCallback)(OTBR_ERROR_MDNS));
262*4a64e381SAndroid Build Coastguard Worker }
263*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(serviceRegistration != nullptr, std::move(aCallback)(OTBR_ERROR_NONE));
264*4a64e381SAndroid Build Coastguard Worker
265*4a64e381SAndroid Build Coastguard Worker serviceRegistration->mUnregisterReceiver = CreateReceiver(std::move(aCallback));
266*4a64e381SAndroid Build Coastguard Worker RemoveServiceRegistration(aName, aType, OTBR_ERROR_NONE);
267*4a64e381SAndroid Build Coastguard Worker
268*4a64e381SAndroid Build Coastguard Worker exit:
269*4a64e381SAndroid Build Coastguard Worker return;
270*4a64e381SAndroid Build Coastguard Worker }
271*4a64e381SAndroid Build Coastguard Worker
PublishHostImpl(const std::string & aName,const AddressList & aAddresses,ResultCallback && aCallback)272*4a64e381SAndroid Build Coastguard Worker otbrError MdnsPublisher::PublishHostImpl(const std::string &aName,
273*4a64e381SAndroid Build Coastguard Worker const AddressList &aAddresses,
274*4a64e381SAndroid Build Coastguard Worker ResultCallback &&aCallback)
275*4a64e381SAndroid Build Coastguard Worker {
276*4a64e381SAndroid Build Coastguard Worker int32_t listenerId = AllocateListenerId();
277*4a64e381SAndroid Build Coastguard Worker TxtList txtList;
278*4a64e381SAndroid Build Coastguard Worker otbrError error = OTBR_ERROR_NONE;
279*4a64e381SAndroid Build Coastguard Worker
280*4a64e381SAndroid Build Coastguard Worker std::vector<std::string> addressStrings;
281*4a64e381SAndroid Build Coastguard Worker
282*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(IsStarted(), error = OTBR_ERROR_MDNS);
283*4a64e381SAndroid Build Coastguard Worker if (mNsdPublisher == nullptr)
284*4a64e381SAndroid Build Coastguard Worker {
285*4a64e381SAndroid Build Coastguard Worker otbrLogWarning("No platform mDNS implementation registered!");
286*4a64e381SAndroid Build Coastguard Worker ExitNow(error = OTBR_ERROR_MDNS);
287*4a64e381SAndroid Build Coastguard Worker }
288*4a64e381SAndroid Build Coastguard Worker
289*4a64e381SAndroid Build Coastguard Worker aCallback = HandleDuplicateHostRegistration(aName, aAddresses, std::move(aCallback));
290*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(!aCallback.IsNull(), error = OTBR_ERROR_INVALID_STATE);
291*4a64e381SAndroid Build Coastguard Worker
292*4a64e381SAndroid Build Coastguard Worker AddHostRegistration(
293*4a64e381SAndroid Build Coastguard Worker MakeUnique<NsdHostRegistration>(aName, aAddresses, /* aCallback= */ nullptr, this, listenerId, mNsdPublisher));
294*4a64e381SAndroid Build Coastguard Worker
295*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Publishing host %s listener ID = %d", aName.c_str(), listenerId);
296*4a64e381SAndroid Build Coastguard Worker
297*4a64e381SAndroid Build Coastguard Worker addressStrings.reserve(aAddresses.size());
298*4a64e381SAndroid Build Coastguard Worker for (const Ip6Address &address : aAddresses)
299*4a64e381SAndroid Build Coastguard Worker {
300*4a64e381SAndroid Build Coastguard Worker addressStrings.push_back(address.ToString());
301*4a64e381SAndroid Build Coastguard Worker }
302*4a64e381SAndroid Build Coastguard Worker
303*4a64e381SAndroid Build Coastguard Worker if (aAddresses.size())
304*4a64e381SAndroid Build Coastguard Worker {
305*4a64e381SAndroid Build Coastguard Worker mNsdPublisher->registerHost(aName, addressStrings, CreateReceiver(std::move(aCallback)), listenerId);
306*4a64e381SAndroid Build Coastguard Worker }
307*4a64e381SAndroid Build Coastguard Worker else
308*4a64e381SAndroid Build Coastguard Worker {
309*4a64e381SAndroid Build Coastguard Worker // No addresses to register.
310*4a64e381SAndroid Build Coastguard Worker std::move(aCallback)(OTBR_ERROR_NONE);
311*4a64e381SAndroid Build Coastguard Worker }
312*4a64e381SAndroid Build Coastguard Worker
313*4a64e381SAndroid Build Coastguard Worker exit:
314*4a64e381SAndroid Build Coastguard Worker return error;
315*4a64e381SAndroid Build Coastguard Worker }
316*4a64e381SAndroid Build Coastguard Worker
PublishKeyImpl(const std::string & aName,const KeyData & aKeyData,ResultCallback && aCallback)317*4a64e381SAndroid Build Coastguard Worker otbrError MdnsPublisher::PublishKeyImpl(const std::string &aName, const KeyData &aKeyData, ResultCallback &&aCallback)
318*4a64e381SAndroid Build Coastguard Worker {
319*4a64e381SAndroid Build Coastguard Worker OTBR_UNUSED_VARIABLE(aName);
320*4a64e381SAndroid Build Coastguard Worker OTBR_UNUSED_VARIABLE(aKeyData);
321*4a64e381SAndroid Build Coastguard Worker OTBR_UNUSED_VARIABLE(aCallback);
322*4a64e381SAndroid Build Coastguard Worker
323*4a64e381SAndroid Build Coastguard Worker DieForNotImplemented(__func__);
324*4a64e381SAndroid Build Coastguard Worker
325*4a64e381SAndroid Build Coastguard Worker return OTBR_ERROR_MDNS;
326*4a64e381SAndroid Build Coastguard Worker }
327*4a64e381SAndroid Build Coastguard Worker
UnpublishHost(const std::string & aName,ResultCallback && aCallback)328*4a64e381SAndroid Build Coastguard Worker void MdnsPublisher::UnpublishHost(const std::string &aName, ResultCallback &&aCallback)
329*4a64e381SAndroid Build Coastguard Worker {
330*4a64e381SAndroid Build Coastguard Worker NsdHostRegistration *hostRegistration = static_cast<NsdHostRegistration *>(FindHostRegistration(aName));
331*4a64e381SAndroid Build Coastguard Worker
332*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(IsStarted(), std::move(aCallback)(OTBR_ERROR_MDNS));
333*4a64e381SAndroid Build Coastguard Worker if (mNsdPublisher == nullptr)
334*4a64e381SAndroid Build Coastguard Worker {
335*4a64e381SAndroid Build Coastguard Worker otbrLogWarning("No platform mDNS implementation registered!");
336*4a64e381SAndroid Build Coastguard Worker ExitNow(std::move(aCallback)(OTBR_ERROR_MDNS));
337*4a64e381SAndroid Build Coastguard Worker }
338*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(hostRegistration != nullptr, std::move(aCallback)(OTBR_ERROR_NONE));
339*4a64e381SAndroid Build Coastguard Worker
340*4a64e381SAndroid Build Coastguard Worker hostRegistration->mUnregisterReceiver = CreateReceiver(std::move(aCallback));
341*4a64e381SAndroid Build Coastguard Worker RemoveHostRegistration(aName, OTBR_ERROR_NONE);
342*4a64e381SAndroid Build Coastguard Worker
343*4a64e381SAndroid Build Coastguard Worker exit:
344*4a64e381SAndroid Build Coastguard Worker return;
345*4a64e381SAndroid Build Coastguard Worker }
346*4a64e381SAndroid Build Coastguard Worker
UnpublishKey(const std::string & aName,ResultCallback && aCallback)347*4a64e381SAndroid Build Coastguard Worker void MdnsPublisher::UnpublishKey(const std::string &aName, ResultCallback &&aCallback)
348*4a64e381SAndroid Build Coastguard Worker {
349*4a64e381SAndroid Build Coastguard Worker OTBR_UNUSED_VARIABLE(aName);
350*4a64e381SAndroid Build Coastguard Worker OTBR_UNUSED_VARIABLE(aCallback);
351*4a64e381SAndroid Build Coastguard Worker
352*4a64e381SAndroid Build Coastguard Worker DieForNotImplemented(__func__);
353*4a64e381SAndroid Build Coastguard Worker }
354*4a64e381SAndroid Build Coastguard Worker
SubscribeService(const std::string & aType,const std::string & aInstanceName)355*4a64e381SAndroid Build Coastguard Worker void MdnsPublisher::SubscribeService(const std::string &aType, const std::string &aInstanceName)
356*4a64e381SAndroid Build Coastguard Worker {
357*4a64e381SAndroid Build Coastguard Worker auto service = std::make_shared<ServiceSubscription>(aType, aInstanceName, *this, mNsdPublisher);
358*4a64e381SAndroid Build Coastguard Worker
359*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(IsStarted(), otbrLogWarning("No platform mDNS implementation registered!"));
360*4a64e381SAndroid Build Coastguard Worker
361*4a64e381SAndroid Build Coastguard Worker mServiceSubscriptions.push_back(std::move(service));
362*4a64e381SAndroid Build Coastguard Worker
363*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Subscribe service %s.%s (total %zu)", aInstanceName.c_str(), aType.c_str(),
364*4a64e381SAndroid Build Coastguard Worker mServiceSubscriptions.size());
365*4a64e381SAndroid Build Coastguard Worker
366*4a64e381SAndroid Build Coastguard Worker if (aInstanceName.empty())
367*4a64e381SAndroid Build Coastguard Worker {
368*4a64e381SAndroid Build Coastguard Worker mServiceSubscriptions.back()->Browse();
369*4a64e381SAndroid Build Coastguard Worker }
370*4a64e381SAndroid Build Coastguard Worker else
371*4a64e381SAndroid Build Coastguard Worker {
372*4a64e381SAndroid Build Coastguard Worker mServiceSubscriptions.back()->Resolve(aInstanceName, aType);
373*4a64e381SAndroid Build Coastguard Worker }
374*4a64e381SAndroid Build Coastguard Worker exit:
375*4a64e381SAndroid Build Coastguard Worker return;
376*4a64e381SAndroid Build Coastguard Worker }
377*4a64e381SAndroid Build Coastguard Worker
UnsubscribeService(const std::string & aType,const std::string & aInstanceName)378*4a64e381SAndroid Build Coastguard Worker void MdnsPublisher::UnsubscribeService(const std::string &aType, const std::string &aInstanceName)
379*4a64e381SAndroid Build Coastguard Worker {
380*4a64e381SAndroid Build Coastguard Worker ServiceSubscriptionList::iterator it;
381*4a64e381SAndroid Build Coastguard Worker
382*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(IsStarted());
383*4a64e381SAndroid Build Coastguard Worker
384*4a64e381SAndroid Build Coastguard Worker it = std::find_if(mServiceSubscriptions.begin(), mServiceSubscriptions.end(),
385*4a64e381SAndroid Build Coastguard Worker [&aType, &aInstanceName](const std::shared_ptr<ServiceSubscription> &aService) {
386*4a64e381SAndroid Build Coastguard Worker return aService->mType == aType && aService->mName == aInstanceName;
387*4a64e381SAndroid Build Coastguard Worker });
388*4a64e381SAndroid Build Coastguard Worker
389*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(it != mServiceSubscriptions.end(),
390*4a64e381SAndroid Build Coastguard Worker otbrLogWarning("The service %s.%s is already unsubscribed.", aInstanceName.c_str(), aType.c_str()));
391*4a64e381SAndroid Build Coastguard Worker
392*4a64e381SAndroid Build Coastguard Worker {
393*4a64e381SAndroid Build Coastguard Worker std::shared_ptr<ServiceSubscription> service = std::move(*it);
394*4a64e381SAndroid Build Coastguard Worker
395*4a64e381SAndroid Build Coastguard Worker mServiceSubscriptions.erase(it);
396*4a64e381SAndroid Build Coastguard Worker }
397*4a64e381SAndroid Build Coastguard Worker
398*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Unsubscribe service %s.%s (left %zu)", aInstanceName.c_str(), aType.c_str(),
399*4a64e381SAndroid Build Coastguard Worker mServiceSubscriptions.size());
400*4a64e381SAndroid Build Coastguard Worker
401*4a64e381SAndroid Build Coastguard Worker exit:
402*4a64e381SAndroid Build Coastguard Worker return;
403*4a64e381SAndroid Build Coastguard Worker }
404*4a64e381SAndroid Build Coastguard Worker
SubscribeHost(const std::string & aHostName)405*4a64e381SAndroid Build Coastguard Worker void MdnsPublisher::SubscribeHost(const std::string &aHostName)
406*4a64e381SAndroid Build Coastguard Worker {
407*4a64e381SAndroid Build Coastguard Worker auto host = std::make_shared<HostSubscription>(aHostName, *this, mNsdPublisher, AllocateListenerId());
408*4a64e381SAndroid Build Coastguard Worker
409*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(IsStarted(), otbrLogWarning("No platform mDNS implementation registered!"));
410*4a64e381SAndroid Build Coastguard Worker
411*4a64e381SAndroid Build Coastguard Worker mNsdPublisher->resolveHost(aHostName, CreateNsdResolveHostCallback(host), host->mListenerId);
412*4a64e381SAndroid Build Coastguard Worker mHostSubscriptions.push_back(std::move(host));
413*4a64e381SAndroid Build Coastguard Worker
414*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Subscribe host %s (total %zu)", aHostName.c_str(), mHostSubscriptions.size());
415*4a64e381SAndroid Build Coastguard Worker
416*4a64e381SAndroid Build Coastguard Worker exit:
417*4a64e381SAndroid Build Coastguard Worker return;
418*4a64e381SAndroid Build Coastguard Worker }
419*4a64e381SAndroid Build Coastguard Worker
UnsubscribeHost(const std::string & aHostName)420*4a64e381SAndroid Build Coastguard Worker void MdnsPublisher::UnsubscribeHost(const std::string &aHostName)
421*4a64e381SAndroid Build Coastguard Worker {
422*4a64e381SAndroid Build Coastguard Worker HostSubscriptionList::iterator it;
423*4a64e381SAndroid Build Coastguard Worker
424*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(IsStarted());
425*4a64e381SAndroid Build Coastguard Worker
426*4a64e381SAndroid Build Coastguard Worker it = std::find_if(
427*4a64e381SAndroid Build Coastguard Worker mHostSubscriptions.begin(), mHostSubscriptions.end(),
428*4a64e381SAndroid Build Coastguard Worker [&aHostName](const std::shared_ptr<HostSubscription> &aHost) { return aHost->mName == aHostName; });
429*4a64e381SAndroid Build Coastguard Worker
430*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(it != mHostSubscriptions.end(),
431*4a64e381SAndroid Build Coastguard Worker otbrLogWarning("The host %s is already unsubscribed.", aHostName.c_str()));
432*4a64e381SAndroid Build Coastguard Worker
433*4a64e381SAndroid Build Coastguard Worker {
434*4a64e381SAndroid Build Coastguard Worker std::shared_ptr<HostSubscription> host = std::move(*it);
435*4a64e381SAndroid Build Coastguard Worker
436*4a64e381SAndroid Build Coastguard Worker mHostSubscriptions.erase(it);
437*4a64e381SAndroid Build Coastguard Worker }
438*4a64e381SAndroid Build Coastguard Worker
439*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Unsubscribe host %s (left %zu)", aHostName.c_str(), mHostSubscriptions.size());
440*4a64e381SAndroid Build Coastguard Worker
441*4a64e381SAndroid Build Coastguard Worker exit:
442*4a64e381SAndroid Build Coastguard Worker return;
443*4a64e381SAndroid Build Coastguard Worker }
444*4a64e381SAndroid Build Coastguard Worker
OnServiceResolveFailedImpl(const std::string & aType,const std::string & aInstanceName,int32_t aErrorCode)445*4a64e381SAndroid Build Coastguard Worker void MdnsPublisher::OnServiceResolveFailedImpl(const std::string &aType,
446*4a64e381SAndroid Build Coastguard Worker const std::string &aInstanceName,
447*4a64e381SAndroid Build Coastguard Worker int32_t aErrorCode)
448*4a64e381SAndroid Build Coastguard Worker {
449*4a64e381SAndroid Build Coastguard Worker OTBR_UNUSED_VARIABLE(aType);
450*4a64e381SAndroid Build Coastguard Worker OTBR_UNUSED_VARIABLE(aInstanceName);
451*4a64e381SAndroid Build Coastguard Worker OTBR_UNUSED_VARIABLE(aErrorCode);
452*4a64e381SAndroid Build Coastguard Worker
453*4a64e381SAndroid Build Coastguard Worker DieForNotImplemented(__func__);
454*4a64e381SAndroid Build Coastguard Worker }
455*4a64e381SAndroid Build Coastguard Worker
OnHostResolveFailedImpl(const std::string & aHostName,int32_t aErrorCode)456*4a64e381SAndroid Build Coastguard Worker void MdnsPublisher::OnHostResolveFailedImpl(const std::string &aHostName, int32_t aErrorCode)
457*4a64e381SAndroid Build Coastguard Worker {
458*4a64e381SAndroid Build Coastguard Worker OTBR_UNUSED_VARIABLE(aHostName);
459*4a64e381SAndroid Build Coastguard Worker OTBR_UNUSED_VARIABLE(aErrorCode);
460*4a64e381SAndroid Build Coastguard Worker
461*4a64e381SAndroid Build Coastguard Worker DieForNotImplemented(__func__);
462*4a64e381SAndroid Build Coastguard Worker }
463*4a64e381SAndroid Build Coastguard Worker
AllocateListenerId(void)464*4a64e381SAndroid Build Coastguard Worker int32_t MdnsPublisher::AllocateListenerId(void)
465*4a64e381SAndroid Build Coastguard Worker {
466*4a64e381SAndroid Build Coastguard Worker if (mNextListenerId == std::numeric_limits<int32_t>::max())
467*4a64e381SAndroid Build Coastguard Worker {
468*4a64e381SAndroid Build Coastguard Worker mNextListenerId = 0;
469*4a64e381SAndroid Build Coastguard Worker }
470*4a64e381SAndroid Build Coastguard Worker return mNextListenerId++;
471*4a64e381SAndroid Build Coastguard Worker }
472*4a64e381SAndroid Build Coastguard Worker
~NsdServiceRegistration(void)473*4a64e381SAndroid Build Coastguard Worker MdnsPublisher::NsdServiceRegistration::~NsdServiceRegistration(void)
474*4a64e381SAndroid Build Coastguard Worker {
475*4a64e381SAndroid Build Coastguard Worker auto nsdPublisher = mNsdPublisher.lock();
476*4a64e381SAndroid Build Coastguard Worker
477*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mPublisher->IsStarted() && nsdPublisher != nullptr);
478*4a64e381SAndroid Build Coastguard Worker
479*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Unpublishing service %s.%s listener ID = %d", mName.c_str(), mType.c_str(), mListenerId);
480*4a64e381SAndroid Build Coastguard Worker
481*4a64e381SAndroid Build Coastguard Worker if (!mUnregisterReceiver)
482*4a64e381SAndroid Build Coastguard Worker {
483*4a64e381SAndroid Build Coastguard Worker mUnregisterReceiver = CreateReceiver([](int) {});
484*4a64e381SAndroid Build Coastguard Worker }
485*4a64e381SAndroid Build Coastguard Worker
486*4a64e381SAndroid Build Coastguard Worker nsdPublisher->unregister(mUnregisterReceiver, mListenerId);
487*4a64e381SAndroid Build Coastguard Worker
488*4a64e381SAndroid Build Coastguard Worker exit:
489*4a64e381SAndroid Build Coastguard Worker return;
490*4a64e381SAndroid Build Coastguard Worker }
491*4a64e381SAndroid Build Coastguard Worker
~NsdHostRegistration(void)492*4a64e381SAndroid Build Coastguard Worker MdnsPublisher::NsdHostRegistration::~NsdHostRegistration(void)
493*4a64e381SAndroid Build Coastguard Worker {
494*4a64e381SAndroid Build Coastguard Worker auto nsdPublisher = mNsdPublisher.lock();
495*4a64e381SAndroid Build Coastguard Worker
496*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mPublisher->IsStarted() && nsdPublisher != nullptr);
497*4a64e381SAndroid Build Coastguard Worker
498*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Unpublishing host %s listener ID = %d", mName.c_str(), mListenerId);
499*4a64e381SAndroid Build Coastguard Worker
500*4a64e381SAndroid Build Coastguard Worker if (!mUnregisterReceiver)
501*4a64e381SAndroid Build Coastguard Worker {
502*4a64e381SAndroid Build Coastguard Worker mUnregisterReceiver = CreateReceiver([](int) {});
503*4a64e381SAndroid Build Coastguard Worker }
504*4a64e381SAndroid Build Coastguard Worker
505*4a64e381SAndroid Build Coastguard Worker nsdPublisher->unregister(mUnregisterReceiver, mListenerId);
506*4a64e381SAndroid Build Coastguard Worker
507*4a64e381SAndroid Build Coastguard Worker exit:
508*4a64e381SAndroid Build Coastguard Worker return;
509*4a64e381SAndroid Build Coastguard Worker }
510*4a64e381SAndroid Build Coastguard Worker
Release(void)511*4a64e381SAndroid Build Coastguard Worker void MdnsPublisher::ServiceSubscription::Release(void)
512*4a64e381SAndroid Build Coastguard Worker {
513*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Browsing service type %s", mType.c_str());
514*4a64e381SAndroid Build Coastguard Worker
515*4a64e381SAndroid Build Coastguard Worker std::vector<std::string> instanceNames;
516*4a64e381SAndroid Build Coastguard Worker
517*4a64e381SAndroid Build Coastguard Worker for (const auto &nameAndResolvers : mResolvers)
518*4a64e381SAndroid Build Coastguard Worker {
519*4a64e381SAndroid Build Coastguard Worker instanceNames.push_back(nameAndResolvers.first);
520*4a64e381SAndroid Build Coastguard Worker }
521*4a64e381SAndroid Build Coastguard Worker for (const auto &name : instanceNames)
522*4a64e381SAndroid Build Coastguard Worker {
523*4a64e381SAndroid Build Coastguard Worker RemoveServiceResolver(name);
524*4a64e381SAndroid Build Coastguard Worker }
525*4a64e381SAndroid Build Coastguard Worker
526*4a64e381SAndroid Build Coastguard Worker mNsdPublisher->stopServiceDiscovery(mBrowseListenerId);
527*4a64e381SAndroid Build Coastguard Worker }
528*4a64e381SAndroid Build Coastguard Worker
Browse(void)529*4a64e381SAndroid Build Coastguard Worker void MdnsPublisher::ServiceSubscription::Browse(void)
530*4a64e381SAndroid Build Coastguard Worker {
531*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mPublisher.IsStarted());
532*4a64e381SAndroid Build Coastguard Worker
533*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Browsing service type %s", mType.c_str());
534*4a64e381SAndroid Build Coastguard Worker
535*4a64e381SAndroid Build Coastguard Worker mNsdPublisher->discoverService(mType, CreateNsdDiscoverServiceCallback(shared_from_this()), mBrowseListenerId);
536*4a64e381SAndroid Build Coastguard Worker
537*4a64e381SAndroid Build Coastguard Worker exit:
538*4a64e381SAndroid Build Coastguard Worker return;
539*4a64e381SAndroid Build Coastguard Worker }
540*4a64e381SAndroid Build Coastguard Worker
Resolve(const std::string & aName,const std::string & aType)541*4a64e381SAndroid Build Coastguard Worker void MdnsPublisher::ServiceSubscription::Resolve(const std::string &aName, const std::string &aType)
542*4a64e381SAndroid Build Coastguard Worker {
543*4a64e381SAndroid Build Coastguard Worker ServiceResolver *resolver = new ServiceResolver(mPublisher.AllocateListenerId(), mNsdPublisher);
544*4a64e381SAndroid Build Coastguard Worker
545*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mPublisher.IsStarted());
546*4a64e381SAndroid Build Coastguard Worker
547*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Resolving service %s.%s", aName.c_str(), aType.c_str());
548*4a64e381SAndroid Build Coastguard Worker
549*4a64e381SAndroid Build Coastguard Worker AddServiceResolver(aName, resolver);
550*4a64e381SAndroid Build Coastguard Worker mNsdPublisher->resolveService(aName, aType, CreateNsdResolveServiceCallback(shared_from_this()),
551*4a64e381SAndroid Build Coastguard Worker resolver->mListenerId);
552*4a64e381SAndroid Build Coastguard Worker
553*4a64e381SAndroid Build Coastguard Worker exit:
554*4a64e381SAndroid Build Coastguard Worker return;
555*4a64e381SAndroid Build Coastguard Worker }
556*4a64e381SAndroid Build Coastguard Worker
AddServiceResolver(const std::string & aName,ServiceResolver * aResolver)557*4a64e381SAndroid Build Coastguard Worker void MdnsPublisher::ServiceSubscription::AddServiceResolver(const std::string &aName, ServiceResolver *aResolver)
558*4a64e381SAndroid Build Coastguard Worker {
559*4a64e381SAndroid Build Coastguard Worker mResolvers[aName].insert(aResolver);
560*4a64e381SAndroid Build Coastguard Worker }
RemoveServiceResolver(const std::string & aName)561*4a64e381SAndroid Build Coastguard Worker void MdnsPublisher::ServiceSubscription::RemoveServiceResolver(const std::string &aName)
562*4a64e381SAndroid Build Coastguard Worker {
563*4a64e381SAndroid Build Coastguard Worker int numResolvers = 0;
564*4a64e381SAndroid Build Coastguard Worker
565*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mResolvers.find(aName) != mResolvers.end());
566*4a64e381SAndroid Build Coastguard Worker
567*4a64e381SAndroid Build Coastguard Worker numResolvers = mResolvers[aName].size();
568*4a64e381SAndroid Build Coastguard Worker
569*4a64e381SAndroid Build Coastguard Worker for (auto resolver : mResolvers[aName])
570*4a64e381SAndroid Build Coastguard Worker {
571*4a64e381SAndroid Build Coastguard Worker delete resolver;
572*4a64e381SAndroid Build Coastguard Worker }
573*4a64e381SAndroid Build Coastguard Worker
574*4a64e381SAndroid Build Coastguard Worker mResolvers.erase(aName);
575*4a64e381SAndroid Build Coastguard Worker
576*4a64e381SAndroid Build Coastguard Worker exit:
577*4a64e381SAndroid Build Coastguard Worker otbrLogDebug("Removed %d service resolver for instance %s", numResolvers, aName.c_str());
578*4a64e381SAndroid Build Coastguard Worker return;
579*4a64e381SAndroid Build Coastguard Worker }
580*4a64e381SAndroid Build Coastguard Worker
581*4a64e381SAndroid Build Coastguard Worker } // namespace Android
582*4a64e381SAndroid Build Coastguard Worker } // namespace otbr
583