xref: /aosp_15_r20/external/ot-br-posix/src/android/mdns_publisher.cpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
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