xref: /aosp_15_r20/external/ot-br-posix/src/mdns/mdns_avahi.hpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker  *    Copyright (c) 2017, 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 /**
30*4a64e381SAndroid Build Coastguard Worker  * @file
31*4a64e381SAndroid Build Coastguard Worker  *   This file includes definition for mDNS publisher based on avahi.
32*4a64e381SAndroid Build Coastguard Worker  */
33*4a64e381SAndroid Build Coastguard Worker 
34*4a64e381SAndroid Build Coastguard Worker #ifndef OTBR_AGENT_MDNS_AVAHI_HPP_
35*4a64e381SAndroid Build Coastguard Worker #define OTBR_AGENT_MDNS_AVAHI_HPP_
36*4a64e381SAndroid Build Coastguard Worker 
37*4a64e381SAndroid Build Coastguard Worker #include "openthread-br/config.h"
38*4a64e381SAndroid Build Coastguard Worker 
39*4a64e381SAndroid Build Coastguard Worker #include <memory>
40*4a64e381SAndroid Build Coastguard Worker #include <set>
41*4a64e381SAndroid Build Coastguard Worker #include <vector>
42*4a64e381SAndroid Build Coastguard Worker 
43*4a64e381SAndroid Build Coastguard Worker #include <avahi-client/client.h>
44*4a64e381SAndroid Build Coastguard Worker #include <avahi-client/lookup.h>
45*4a64e381SAndroid Build Coastguard Worker #include <avahi-client/publish.h>
46*4a64e381SAndroid Build Coastguard Worker #include <avahi-common/domain.h>
47*4a64e381SAndroid Build Coastguard Worker #include <avahi-common/watch.h>
48*4a64e381SAndroid Build Coastguard Worker 
49*4a64e381SAndroid Build Coastguard Worker #include "mdns.hpp"
50*4a64e381SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
51*4a64e381SAndroid Build Coastguard Worker #include "common/mainloop.hpp"
52*4a64e381SAndroid Build Coastguard Worker #include "common/time.hpp"
53*4a64e381SAndroid Build Coastguard Worker 
54*4a64e381SAndroid Build Coastguard Worker /**
55*4a64e381SAndroid Build Coastguard Worker  * @addtogroup border-router-mdns
56*4a64e381SAndroid Build Coastguard Worker  *
57*4a64e381SAndroid Build Coastguard Worker  * @brief
58*4a64e381SAndroid Build Coastguard Worker  *   This module includes definition for avahi-based mDNS publisher.
59*4a64e381SAndroid Build Coastguard Worker  *
60*4a64e381SAndroid Build Coastguard Worker  * @{
61*4a64e381SAndroid Build Coastguard Worker  */
62*4a64e381SAndroid Build Coastguard Worker 
63*4a64e381SAndroid Build Coastguard Worker namespace otbr {
64*4a64e381SAndroid Build Coastguard Worker 
65*4a64e381SAndroid Build Coastguard Worker namespace Mdns {
66*4a64e381SAndroid Build Coastguard Worker 
67*4a64e381SAndroid Build Coastguard Worker class AvahiPoller;
68*4a64e381SAndroid Build Coastguard Worker 
69*4a64e381SAndroid Build Coastguard Worker /**
70*4a64e381SAndroid Build Coastguard Worker  * This class implements mDNS publisher with avahi.
71*4a64e381SAndroid Build Coastguard Worker  */
72*4a64e381SAndroid Build Coastguard Worker class PublisherAvahi : public Publisher
73*4a64e381SAndroid Build Coastguard Worker {
74*4a64e381SAndroid Build Coastguard Worker public:
75*4a64e381SAndroid Build Coastguard Worker     PublisherAvahi(StateCallback aStateCallback);
76*4a64e381SAndroid Build Coastguard Worker     ~PublisherAvahi(void) override;
77*4a64e381SAndroid Build Coastguard Worker 
78*4a64e381SAndroid Build Coastguard Worker     void      UnpublishService(const std::string &aName, const std::string &aType, ResultCallback &&aCallback) override;
79*4a64e381SAndroid Build Coastguard Worker     void      UnpublishHost(const std::string &aName, ResultCallback &&aCallback) override;
80*4a64e381SAndroid Build Coastguard Worker     void      UnpublishKey(const std::string &aName, ResultCallback &&aCallback) override;
81*4a64e381SAndroid Build Coastguard Worker     void      SubscribeService(const std::string &aType, const std::string &aInstanceName) override;
82*4a64e381SAndroid Build Coastguard Worker     void      UnsubscribeService(const std::string &aType, const std::string &aInstanceName) override;
83*4a64e381SAndroid Build Coastguard Worker     void      SubscribeHost(const std::string &aHostName) override;
84*4a64e381SAndroid Build Coastguard Worker     void      UnsubscribeHost(const std::string &aHostName) override;
85*4a64e381SAndroid Build Coastguard Worker     otbrError Start(void) override;
86*4a64e381SAndroid Build Coastguard Worker     bool      IsStarted(void) const override;
87*4a64e381SAndroid Build Coastguard Worker     void      Stop(void) override;
88*4a64e381SAndroid Build Coastguard Worker 
89*4a64e381SAndroid Build Coastguard Worker protected:
90*4a64e381SAndroid Build Coastguard Worker     otbrError PublishServiceImpl(const std::string &aHostName,
91*4a64e381SAndroid Build Coastguard Worker                                  const std::string &aName,
92*4a64e381SAndroid Build Coastguard Worker                                  const std::string &aType,
93*4a64e381SAndroid Build Coastguard Worker                                  const SubTypeList &aSubTypeList,
94*4a64e381SAndroid Build Coastguard Worker                                  uint16_t           aPort,
95*4a64e381SAndroid Build Coastguard Worker                                  const TxtData     &aTxtData,
96*4a64e381SAndroid Build Coastguard Worker                                  ResultCallback   &&aCallback) override;
97*4a64e381SAndroid Build Coastguard Worker     otbrError PublishHostImpl(const std::string &aName,
98*4a64e381SAndroid Build Coastguard Worker                               const AddressList &aAddresses,
99*4a64e381SAndroid Build Coastguard Worker                               ResultCallback   &&aCallback) override;
100*4a64e381SAndroid Build Coastguard Worker     otbrError PublishKeyImpl(const std::string &aName, const KeyData &aKeyData, ResultCallback &&aCallback) override;
101*4a64e381SAndroid Build Coastguard Worker     void      OnServiceResolveFailedImpl(const std::string &aType,
102*4a64e381SAndroid Build Coastguard Worker                                          const std::string &aInstanceName,
103*4a64e381SAndroid Build Coastguard Worker                                          int32_t            aErrorCode) override;
104*4a64e381SAndroid Build Coastguard Worker     void      OnHostResolveFailedImpl(const std::string &aHostName, int32_t aErrorCode) override;
105*4a64e381SAndroid Build Coastguard Worker     otbrError DnsErrorToOtbrError(int32_t aErrorCode) override;
106*4a64e381SAndroid Build Coastguard Worker 
107*4a64e381SAndroid Build Coastguard Worker private:
108*4a64e381SAndroid Build Coastguard Worker     static constexpr size_t   kMaxSizeOfTxtRecord = 1024;
109*4a64e381SAndroid Build Coastguard Worker     static constexpr uint32_t kDefaultTtl         = 10; // In seconds.
110*4a64e381SAndroid Build Coastguard Worker     static constexpr uint16_t kDnsKeyRecordType   = 25;
111*4a64e381SAndroid Build Coastguard Worker 
112*4a64e381SAndroid Build Coastguard Worker     class AvahiServiceRegistration : public ServiceRegistration
113*4a64e381SAndroid Build Coastguard Worker     {
114*4a64e381SAndroid Build Coastguard Worker     public:
AvahiServiceRegistration(const std::string & aHostName,const std::string & aName,const std::string & aType,const SubTypeList & aSubTypeList,uint16_t aPort,const TxtData & aTxtData,ResultCallback && aCallback,AvahiEntryGroup * aEntryGroup,PublisherAvahi * aPublisher)115*4a64e381SAndroid Build Coastguard Worker         AvahiServiceRegistration(const std::string &aHostName,
116*4a64e381SAndroid Build Coastguard Worker                                  const std::string &aName,
117*4a64e381SAndroid Build Coastguard Worker                                  const std::string &aType,
118*4a64e381SAndroid Build Coastguard Worker                                  const SubTypeList &aSubTypeList,
119*4a64e381SAndroid Build Coastguard Worker                                  uint16_t           aPort,
120*4a64e381SAndroid Build Coastguard Worker                                  const TxtData     &aTxtData,
121*4a64e381SAndroid Build Coastguard Worker                                  ResultCallback   &&aCallback,
122*4a64e381SAndroid Build Coastguard Worker                                  AvahiEntryGroup   *aEntryGroup,
123*4a64e381SAndroid Build Coastguard Worker                                  PublisherAvahi    *aPublisher)
124*4a64e381SAndroid Build Coastguard Worker             : ServiceRegistration(aHostName,
125*4a64e381SAndroid Build Coastguard Worker                                   aName,
126*4a64e381SAndroid Build Coastguard Worker                                   aType,
127*4a64e381SAndroid Build Coastguard Worker                                   aSubTypeList,
128*4a64e381SAndroid Build Coastguard Worker                                   aPort,
129*4a64e381SAndroid Build Coastguard Worker                                   aTxtData,
130*4a64e381SAndroid Build Coastguard Worker                                   std::move(aCallback),
131*4a64e381SAndroid Build Coastguard Worker                                   aPublisher)
132*4a64e381SAndroid Build Coastguard Worker             , mEntryGroup(aEntryGroup)
133*4a64e381SAndroid Build Coastguard Worker         {
134*4a64e381SAndroid Build Coastguard Worker         }
135*4a64e381SAndroid Build Coastguard Worker 
136*4a64e381SAndroid Build Coastguard Worker         ~AvahiServiceRegistration(void) override;
GetEntryGroup(void) const137*4a64e381SAndroid Build Coastguard Worker         const AvahiEntryGroup *GetEntryGroup(void) const { return mEntryGroup; }
138*4a64e381SAndroid Build Coastguard Worker 
139*4a64e381SAndroid Build Coastguard Worker     private:
140*4a64e381SAndroid Build Coastguard Worker         AvahiEntryGroup *mEntryGroup;
141*4a64e381SAndroid Build Coastguard Worker     };
142*4a64e381SAndroid Build Coastguard Worker 
143*4a64e381SAndroid Build Coastguard Worker     class AvahiHostRegistration : public HostRegistration
144*4a64e381SAndroid Build Coastguard Worker     {
145*4a64e381SAndroid Build Coastguard Worker     public:
AvahiHostRegistration(const std::string & aName,const AddressList & aAddresses,ResultCallback && aCallback,AvahiEntryGroup * aEntryGroup,PublisherAvahi * aPublisher)146*4a64e381SAndroid Build Coastguard Worker         AvahiHostRegistration(const std::string &aName,
147*4a64e381SAndroid Build Coastguard Worker                               const AddressList &aAddresses,
148*4a64e381SAndroid Build Coastguard Worker                               ResultCallback   &&aCallback,
149*4a64e381SAndroid Build Coastguard Worker                               AvahiEntryGroup   *aEntryGroup,
150*4a64e381SAndroid Build Coastguard Worker                               PublisherAvahi    *aPublisher)
151*4a64e381SAndroid Build Coastguard Worker             : HostRegistration(aName, aAddresses, std::move(aCallback), aPublisher)
152*4a64e381SAndroid Build Coastguard Worker             , mEntryGroup(aEntryGroup)
153*4a64e381SAndroid Build Coastguard Worker         {
154*4a64e381SAndroid Build Coastguard Worker         }
155*4a64e381SAndroid Build Coastguard Worker 
156*4a64e381SAndroid Build Coastguard Worker         ~AvahiHostRegistration(void) override;
GetEntryGroup(void) const157*4a64e381SAndroid Build Coastguard Worker         const AvahiEntryGroup *GetEntryGroup(void) const { return mEntryGroup; }
158*4a64e381SAndroid Build Coastguard Worker 
159*4a64e381SAndroid Build Coastguard Worker     private:
160*4a64e381SAndroid Build Coastguard Worker         AvahiEntryGroup *mEntryGroup;
161*4a64e381SAndroid Build Coastguard Worker     };
162*4a64e381SAndroid Build Coastguard Worker 
163*4a64e381SAndroid Build Coastguard Worker     class AvahiKeyRegistration : public KeyRegistration
164*4a64e381SAndroid Build Coastguard Worker     {
165*4a64e381SAndroid Build Coastguard Worker     public:
AvahiKeyRegistration(const std::string & aName,const KeyData & aKeyData,ResultCallback && aCallback,AvahiEntryGroup * aEntryGroup,PublisherAvahi * aPublisher)166*4a64e381SAndroid Build Coastguard Worker         AvahiKeyRegistration(const std::string &aName,
167*4a64e381SAndroid Build Coastguard Worker                              const KeyData     &aKeyData,
168*4a64e381SAndroid Build Coastguard Worker                              ResultCallback   &&aCallback,
169*4a64e381SAndroid Build Coastguard Worker                              AvahiEntryGroup   *aEntryGroup,
170*4a64e381SAndroid Build Coastguard Worker                              PublisherAvahi    *aPublisher)
171*4a64e381SAndroid Build Coastguard Worker             : KeyRegistration(aName, aKeyData, std::move(aCallback), aPublisher)
172*4a64e381SAndroid Build Coastguard Worker             , mEntryGroup(aEntryGroup)
173*4a64e381SAndroid Build Coastguard Worker         {
174*4a64e381SAndroid Build Coastguard Worker         }
175*4a64e381SAndroid Build Coastguard Worker 
176*4a64e381SAndroid Build Coastguard Worker         ~AvahiKeyRegistration(void) override;
GetEntryGroup(void) const177*4a64e381SAndroid Build Coastguard Worker         const AvahiEntryGroup *GetEntryGroup(void) const { return mEntryGroup; }
178*4a64e381SAndroid Build Coastguard Worker 
179*4a64e381SAndroid Build Coastguard Worker     private:
180*4a64e381SAndroid Build Coastguard Worker         AvahiEntryGroup *mEntryGroup;
181*4a64e381SAndroid Build Coastguard Worker     };
182*4a64e381SAndroid Build Coastguard Worker 
183*4a64e381SAndroid Build Coastguard Worker     struct Subscription : private ::NonCopyable
184*4a64e381SAndroid Build Coastguard Worker     {
185*4a64e381SAndroid Build Coastguard Worker         PublisherAvahi *mPublisherAvahi;
186*4a64e381SAndroid Build Coastguard Worker 
Subscriptionotbr::Mdns::PublisherAvahi::Subscription187*4a64e381SAndroid Build Coastguard Worker         explicit Subscription(PublisherAvahi &aPublisherAvahi)
188*4a64e381SAndroid Build Coastguard Worker             : mPublisherAvahi(&aPublisherAvahi)
189*4a64e381SAndroid Build Coastguard Worker         {
190*4a64e381SAndroid Build Coastguard Worker         }
191*4a64e381SAndroid Build Coastguard Worker     };
192*4a64e381SAndroid Build Coastguard Worker 
193*4a64e381SAndroid Build Coastguard Worker     struct HostSubscription : public Subscription
194*4a64e381SAndroid Build Coastguard Worker     {
HostSubscriptionotbr::Mdns::PublisherAvahi::HostSubscription195*4a64e381SAndroid Build Coastguard Worker         explicit HostSubscription(PublisherAvahi &aAvahiPublisher, std::string aHostName)
196*4a64e381SAndroid Build Coastguard Worker             : Subscription(aAvahiPublisher)
197*4a64e381SAndroid Build Coastguard Worker             , mHostName(std::move(aHostName))
198*4a64e381SAndroid Build Coastguard Worker             , mRecordBrowser(nullptr)
199*4a64e381SAndroid Build Coastguard Worker         {
200*4a64e381SAndroid Build Coastguard Worker         }
201*4a64e381SAndroid Build Coastguard Worker 
~HostSubscriptionotbr::Mdns::PublisherAvahi::HostSubscription202*4a64e381SAndroid Build Coastguard Worker         ~HostSubscription() { Release(); }
203*4a64e381SAndroid Build Coastguard Worker 
204*4a64e381SAndroid Build Coastguard Worker         void        Release(void);
205*4a64e381SAndroid Build Coastguard Worker         void        Resolve(void);
206*4a64e381SAndroid Build Coastguard Worker         static void HandleResolveResult(AvahiRecordBrowser    *aRecordBrowser,
207*4a64e381SAndroid Build Coastguard Worker                                         AvahiIfIndex           aInterfaceIndex,
208*4a64e381SAndroid Build Coastguard Worker                                         AvahiProtocol          aProtocol,
209*4a64e381SAndroid Build Coastguard Worker                                         AvahiBrowserEvent      aEvent,
210*4a64e381SAndroid Build Coastguard Worker                                         const char            *aName,
211*4a64e381SAndroid Build Coastguard Worker                                         uint16_t               aClazz,
212*4a64e381SAndroid Build Coastguard Worker                                         uint16_t               aType,
213*4a64e381SAndroid Build Coastguard Worker                                         const void            *aRdata,
214*4a64e381SAndroid Build Coastguard Worker                                         size_t                 aSize,
215*4a64e381SAndroid Build Coastguard Worker                                         AvahiLookupResultFlags aFlags,
216*4a64e381SAndroid Build Coastguard Worker                                         void                  *aContext);
217*4a64e381SAndroid Build Coastguard Worker 
218*4a64e381SAndroid Build Coastguard Worker         void HandleResolveResult(AvahiRecordBrowser    *aRecordBrowser,
219*4a64e381SAndroid Build Coastguard Worker                                  AvahiIfIndex           aInterfaceIndex,
220*4a64e381SAndroid Build Coastguard Worker                                  AvahiProtocol          aProtocol,
221*4a64e381SAndroid Build Coastguard Worker                                  AvahiBrowserEvent      aEvent,
222*4a64e381SAndroid Build Coastguard Worker                                  const char            *aName,
223*4a64e381SAndroid Build Coastguard Worker                                  uint16_t               aClazz,
224*4a64e381SAndroid Build Coastguard Worker                                  uint16_t               aType,
225*4a64e381SAndroid Build Coastguard Worker                                  const void            *aRdata,
226*4a64e381SAndroid Build Coastguard Worker                                  size_t                 aSize,
227*4a64e381SAndroid Build Coastguard Worker                                  AvahiLookupResultFlags aFlags);
228*4a64e381SAndroid Build Coastguard Worker 
229*4a64e381SAndroid Build Coastguard Worker         std::string         mHostName;
230*4a64e381SAndroid Build Coastguard Worker         DiscoveredHostInfo  mHostInfo;
231*4a64e381SAndroid Build Coastguard Worker         AvahiRecordBrowser *mRecordBrowser;
232*4a64e381SAndroid Build Coastguard Worker     };
233*4a64e381SAndroid Build Coastguard Worker 
234*4a64e381SAndroid Build Coastguard Worker     struct ServiceResolver
235*4a64e381SAndroid Build Coastguard Worker     {
~ServiceResolverotbr::Mdns::PublisherAvahi::ServiceResolver236*4a64e381SAndroid Build Coastguard Worker         ~ServiceResolver()
237*4a64e381SAndroid Build Coastguard Worker         {
238*4a64e381SAndroid Build Coastguard Worker             if (mServiceResolver)
239*4a64e381SAndroid Build Coastguard Worker             {
240*4a64e381SAndroid Build Coastguard Worker                 avahi_service_resolver_free(mServiceResolver);
241*4a64e381SAndroid Build Coastguard Worker             }
242*4a64e381SAndroid Build Coastguard Worker             if (mRecordBrowser)
243*4a64e381SAndroid Build Coastguard Worker             {
244*4a64e381SAndroid Build Coastguard Worker                 avahi_record_browser_free(mRecordBrowser);
245*4a64e381SAndroid Build Coastguard Worker             }
246*4a64e381SAndroid Build Coastguard Worker         }
247*4a64e381SAndroid Build Coastguard Worker 
248*4a64e381SAndroid Build Coastguard Worker         static void HandleResolveServiceResult(AvahiServiceResolver  *aServiceResolver,
249*4a64e381SAndroid Build Coastguard Worker                                                AvahiIfIndex           aInterfaceIndex,
250*4a64e381SAndroid Build Coastguard Worker                                                AvahiProtocol          Protocol,
251*4a64e381SAndroid Build Coastguard Worker                                                AvahiResolverEvent     aEvent,
252*4a64e381SAndroid Build Coastguard Worker                                                const char            *aName,
253*4a64e381SAndroid Build Coastguard Worker                                                const char            *aType,
254*4a64e381SAndroid Build Coastguard Worker                                                const char            *aDomain,
255*4a64e381SAndroid Build Coastguard Worker                                                const char            *aHostName,
256*4a64e381SAndroid Build Coastguard Worker                                                const AvahiAddress    *aAddress,
257*4a64e381SAndroid Build Coastguard Worker                                                uint16_t               aPort,
258*4a64e381SAndroid Build Coastguard Worker                                                AvahiStringList       *aTxt,
259*4a64e381SAndroid Build Coastguard Worker                                                AvahiLookupResultFlags aFlags,
260*4a64e381SAndroid Build Coastguard Worker                                                void                  *aContext);
261*4a64e381SAndroid Build Coastguard Worker 
262*4a64e381SAndroid Build Coastguard Worker         void HandleResolveServiceResult(AvahiServiceResolver  *aServiceResolver,
263*4a64e381SAndroid Build Coastguard Worker                                         AvahiIfIndex           aInterfaceIndex,
264*4a64e381SAndroid Build Coastguard Worker                                         AvahiProtocol          Protocol,
265*4a64e381SAndroid Build Coastguard Worker                                         AvahiResolverEvent     aEvent,
266*4a64e381SAndroid Build Coastguard Worker                                         const char            *aName,
267*4a64e381SAndroid Build Coastguard Worker                                         const char            *aType,
268*4a64e381SAndroid Build Coastguard Worker                                         const char            *aDomain,
269*4a64e381SAndroid Build Coastguard Worker                                         const char            *aHostName,
270*4a64e381SAndroid Build Coastguard Worker                                         const AvahiAddress    *aAddress,
271*4a64e381SAndroid Build Coastguard Worker                                         uint16_t               aPort,
272*4a64e381SAndroid Build Coastguard Worker                                         AvahiStringList       *aTxt,
273*4a64e381SAndroid Build Coastguard Worker                                         AvahiLookupResultFlags aFlags);
274*4a64e381SAndroid Build Coastguard Worker 
275*4a64e381SAndroid Build Coastguard Worker         static void HandleResolveHostResult(AvahiRecordBrowser    *aRecordBrowser,
276*4a64e381SAndroid Build Coastguard Worker                                             AvahiIfIndex           aInterfaceIndex,
277*4a64e381SAndroid Build Coastguard Worker                                             AvahiProtocol          aProtocol,
278*4a64e381SAndroid Build Coastguard Worker                                             AvahiBrowserEvent      aEvent,
279*4a64e381SAndroid Build Coastguard Worker                                             const char            *aName,
280*4a64e381SAndroid Build Coastguard Worker                                             uint16_t               aClazz,
281*4a64e381SAndroid Build Coastguard Worker                                             uint16_t               aType,
282*4a64e381SAndroid Build Coastguard Worker                                             const void            *aRdata,
283*4a64e381SAndroid Build Coastguard Worker                                             size_t                 aSize,
284*4a64e381SAndroid Build Coastguard Worker                                             AvahiLookupResultFlags aFlags,
285*4a64e381SAndroid Build Coastguard Worker                                             void                  *aContext);
286*4a64e381SAndroid Build Coastguard Worker 
287*4a64e381SAndroid Build Coastguard Worker         void HandleResolveHostResult(AvahiRecordBrowser    *aRecordBrowser,
288*4a64e381SAndroid Build Coastguard Worker                                      AvahiIfIndex           aInterfaceIndex,
289*4a64e381SAndroid Build Coastguard Worker                                      AvahiProtocol          aProtocol,
290*4a64e381SAndroid Build Coastguard Worker                                      AvahiBrowserEvent      aEvent,
291*4a64e381SAndroid Build Coastguard Worker                                      const char            *aName,
292*4a64e381SAndroid Build Coastguard Worker                                      uint16_t               aClazz,
293*4a64e381SAndroid Build Coastguard Worker                                      uint16_t               aType,
294*4a64e381SAndroid Build Coastguard Worker                                      const void            *aRdata,
295*4a64e381SAndroid Build Coastguard Worker                                      size_t                 aSize,
296*4a64e381SAndroid Build Coastguard Worker                                      AvahiLookupResultFlags aFlags);
297*4a64e381SAndroid Build Coastguard Worker 
298*4a64e381SAndroid Build Coastguard Worker         std::string            mType;
299*4a64e381SAndroid Build Coastguard Worker         PublisherAvahi        *mPublisherAvahi;
300*4a64e381SAndroid Build Coastguard Worker         AvahiServiceResolver  *mServiceResolver = nullptr;
301*4a64e381SAndroid Build Coastguard Worker         AvahiRecordBrowser    *mRecordBrowser   = nullptr;
302*4a64e381SAndroid Build Coastguard Worker         DiscoveredInstanceInfo mInstanceInfo;
303*4a64e381SAndroid Build Coastguard Worker     };
304*4a64e381SAndroid Build Coastguard Worker     struct ServiceSubscription : public Subscription
305*4a64e381SAndroid Build Coastguard Worker     {
ServiceSubscriptionotbr::Mdns::PublisherAvahi::ServiceSubscription306*4a64e381SAndroid Build Coastguard Worker         explicit ServiceSubscription(PublisherAvahi &aPublisherAvahi, std::string aType, std::string aInstanceName)
307*4a64e381SAndroid Build Coastguard Worker             : Subscription(aPublisherAvahi)
308*4a64e381SAndroid Build Coastguard Worker             , mType(std::move(aType))
309*4a64e381SAndroid Build Coastguard Worker             , mInstanceName(std::move(aInstanceName))
310*4a64e381SAndroid Build Coastguard Worker             , mServiceBrowser(nullptr)
311*4a64e381SAndroid Build Coastguard Worker         {
312*4a64e381SAndroid Build Coastguard Worker         }
313*4a64e381SAndroid Build Coastguard Worker 
~ServiceSubscriptionotbr::Mdns::PublisherAvahi::ServiceSubscription314*4a64e381SAndroid Build Coastguard Worker         ~ServiceSubscription() { Release(); }
315*4a64e381SAndroid Build Coastguard Worker 
316*4a64e381SAndroid Build Coastguard Worker         void Release(void);
317*4a64e381SAndroid Build Coastguard Worker         void Browse(void);
318*4a64e381SAndroid Build Coastguard Worker         void Resolve(uint32_t           aInterfaceIndex,
319*4a64e381SAndroid Build Coastguard Worker                      AvahiProtocol      aProtocol,
320*4a64e381SAndroid Build Coastguard Worker                      const std::string &aInstanceName,
321*4a64e381SAndroid Build Coastguard Worker                      const std::string &aType);
322*4a64e381SAndroid Build Coastguard Worker         void AddServiceResolver(const std::string &aInstanceName, ServiceResolver *aServiceResolver);
323*4a64e381SAndroid Build Coastguard Worker         void RemoveServiceResolver(const std::string &aInstanceName);
324*4a64e381SAndroid Build Coastguard Worker 
325*4a64e381SAndroid Build Coastguard Worker         static void HandleBrowseResult(AvahiServiceBrowser   *aServiceBrowser,
326*4a64e381SAndroid Build Coastguard Worker                                        AvahiIfIndex           aInterfaceIndex,
327*4a64e381SAndroid Build Coastguard Worker                                        AvahiProtocol          aProtocol,
328*4a64e381SAndroid Build Coastguard Worker                                        AvahiBrowserEvent      aEvent,
329*4a64e381SAndroid Build Coastguard Worker                                        const char            *aName,
330*4a64e381SAndroid Build Coastguard Worker                                        const char            *aType,
331*4a64e381SAndroid Build Coastguard Worker                                        const char            *aDomain,
332*4a64e381SAndroid Build Coastguard Worker                                        AvahiLookupResultFlags aFlags,
333*4a64e381SAndroid Build Coastguard Worker                                        void                  *aContext);
334*4a64e381SAndroid Build Coastguard Worker 
335*4a64e381SAndroid Build Coastguard Worker         void HandleBrowseResult(AvahiServiceBrowser   *aServiceBrowser,
336*4a64e381SAndroid Build Coastguard Worker                                 AvahiIfIndex           aInterfaceIndex,
337*4a64e381SAndroid Build Coastguard Worker                                 AvahiProtocol          aProtocol,
338*4a64e381SAndroid Build Coastguard Worker                                 AvahiBrowserEvent      aEvent,
339*4a64e381SAndroid Build Coastguard Worker                                 const char            *aName,
340*4a64e381SAndroid Build Coastguard Worker                                 const char            *aType,
341*4a64e381SAndroid Build Coastguard Worker                                 const char            *aDomain,
342*4a64e381SAndroid Build Coastguard Worker                                 AvahiLookupResultFlags aFlags);
343*4a64e381SAndroid Build Coastguard Worker 
344*4a64e381SAndroid Build Coastguard Worker         std::string          mType;
345*4a64e381SAndroid Build Coastguard Worker         std::string          mInstanceName;
346*4a64e381SAndroid Build Coastguard Worker         AvahiServiceBrowser *mServiceBrowser;
347*4a64e381SAndroid Build Coastguard Worker 
348*4a64e381SAndroid Build Coastguard Worker         using ServiceResolversMap = std::map<std::string, std::set<ServiceResolver *>>;
349*4a64e381SAndroid Build Coastguard Worker         ServiceResolversMap mServiceResolvers;
350*4a64e381SAndroid Build Coastguard Worker     };
351*4a64e381SAndroid Build Coastguard Worker 
352*4a64e381SAndroid Build Coastguard Worker     typedef std::vector<std::unique_ptr<ServiceSubscription>> ServiceSubscriptionList;
353*4a64e381SAndroid Build Coastguard Worker     typedef std::vector<std::unique_ptr<HostSubscription>>    HostSubscriptionList;
354*4a64e381SAndroid Build Coastguard Worker 
355*4a64e381SAndroid Build Coastguard Worker     static void HandleClientState(AvahiClient *aClient, AvahiClientState aState, void *aContext);
356*4a64e381SAndroid Build Coastguard Worker     void        HandleClientState(AvahiClient *aClient, AvahiClientState aState);
357*4a64e381SAndroid Build Coastguard Worker 
358*4a64e381SAndroid Build Coastguard Worker     AvahiEntryGroup *CreateGroup(AvahiClient *aClient);
359*4a64e381SAndroid Build Coastguard Worker     static void      ReleaseGroup(AvahiEntryGroup *aGroup);
360*4a64e381SAndroid Build Coastguard Worker 
361*4a64e381SAndroid Build Coastguard Worker     static void HandleGroupState(AvahiEntryGroup *aGroup, AvahiEntryGroupState aState, void *aContext);
362*4a64e381SAndroid Build Coastguard Worker     void        HandleGroupState(AvahiEntryGroup *aGroup, AvahiEntryGroupState aState);
363*4a64e381SAndroid Build Coastguard Worker     void        CallHostOrServiceCallback(AvahiEntryGroup *aGroup, otbrError aError);
364*4a64e381SAndroid Build Coastguard Worker 
365*4a64e381SAndroid Build Coastguard Worker     static otbrError TxtDataToAvahiStringList(const TxtData    &aTxtData,
366*4a64e381SAndroid Build Coastguard Worker                                               AvahiStringList  *aBuffer,
367*4a64e381SAndroid Build Coastguard Worker                                               size_t            aBufferSize,
368*4a64e381SAndroid Build Coastguard Worker                                               AvahiStringList *&aHead);
369*4a64e381SAndroid Build Coastguard Worker 
370*4a64e381SAndroid Build Coastguard Worker     ServiceRegistration *FindServiceRegistration(const AvahiEntryGroup *aEntryGroup);
371*4a64e381SAndroid Build Coastguard Worker     HostRegistration    *FindHostRegistration(const AvahiEntryGroup *aEntryGroup);
372*4a64e381SAndroid Build Coastguard Worker     KeyRegistration     *FindKeyRegistration(const AvahiEntryGroup *aEntryGroup);
373*4a64e381SAndroid Build Coastguard Worker 
374*4a64e381SAndroid Build Coastguard Worker     AvahiClient                 *mClient;
375*4a64e381SAndroid Build Coastguard Worker     std::unique_ptr<AvahiPoller> mPoller;
376*4a64e381SAndroid Build Coastguard Worker     State                        mState;
377*4a64e381SAndroid Build Coastguard Worker     StateCallback                mStateCallback;
378*4a64e381SAndroid Build Coastguard Worker 
379*4a64e381SAndroid Build Coastguard Worker     ServiceSubscriptionList mSubscribedServices;
380*4a64e381SAndroid Build Coastguard Worker     HostSubscriptionList    mSubscribedHosts;
381*4a64e381SAndroid Build Coastguard Worker };
382*4a64e381SAndroid Build Coastguard Worker 
383*4a64e381SAndroid Build Coastguard Worker } // namespace Mdns
384*4a64e381SAndroid Build Coastguard Worker 
385*4a64e381SAndroid Build Coastguard Worker } // namespace otbr
386*4a64e381SAndroid Build Coastguard Worker 
387*4a64e381SAndroid Build Coastguard Worker /**
388*4a64e381SAndroid Build Coastguard Worker  * @}
389*4a64e381SAndroid Build Coastguard Worker  */
390*4a64e381SAndroid Build Coastguard Worker #endif // OTBR_AGENT_MDNS_AVAHI_HPP_
391