Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / ot-br-posix / repo / src / mdns / mdns_avahi.hpp
1 /*
2  *    Copyright (c) 2017, The OpenThread Authors.
3  *    All rights reserved.
4  *
5  *    Redistribution and use in source and binary forms, with or without
6  *    modification, are permitted provided that the following conditions are met:
7  *    1. Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *    2. Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *    3. Neither the name of the copyright holder nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *    POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 /**
30  * @file
31  *   This file includes definition for MDNS service based on avahi.
32  */
33
34 #ifndef OTBR_AGENT_MDNS_AVAHI_HPP_
35 #define OTBR_AGENT_MDNS_AVAHI_HPP_
36
37 #include <vector>
38
39 #include <avahi-client/client.h>
40 #include <avahi-client/publish.h>
41 #include <avahi-common/domain.h>
42 #include <avahi-common/watch.h>
43
44 #include "mdns.hpp"
45
46 /**
47  * @addtogroup border-router-mdns
48  *
49  * @brief
50  *   This module includes definition for avahi-based MDNS service.
51  *
52  * @{
53  */
54
55 /**
56  * This structure implements AvahiWatch.
57  *
58  */
59 struct AvahiWatch
60 {
61     int                mFd;       ///< The file descriptor to watch.
62     AvahiWatchEvent    mEvents;   ///< The interested events.
63     int                mHappened; ///< The events happened.
64     AvahiWatchCallback mCallback; ///< The function to be called when interested events happened on mFd.
65     void *             mContext;  ///< A pointer to application-specific context.
66     void *             mPoller;   ///< The poller created this watch.
67
68     /**
69      * The constructor to initialize an Avahi watch.
70      *
71      * @param[in]   aFd         The file descriptor to watch.
72      * @param[in]   aEvents     The events to watch.
73      * @param[in]   aCallback   The function to be called when events happend on this file descriptor.
74      * @param[in]   aContext    A pointer to application-specific context.
75      * @param[in]   aPoller     The Poller this watcher belongs to.
76      *
77      */
78     AvahiWatch(int aFd, AvahiWatchEvent aEvents, AvahiWatchCallback aCallback, void *aContext, void *aPoller)
79         : mFd(aFd)
80         , mEvents(aEvents)
81         , mCallback(aCallback)
82         , mContext(aContext)
83         , mPoller(aPoller)
84     {
85     }
86 };
87
88 /**
89  * This structure implements the AvahiTimeout.
90  *
91  */
92 struct AvahiTimeout
93 {
94     unsigned long        mTimeout;  ///< Absolute time when this timer timeout.
95     AvahiTimeoutCallback mCallback; ///< The function to be called when timeout.
96     void *               mContext;  ///< The pointer to application-specific context.
97     void *               mPoller;   ///< The poller created this timer.
98
99     /**
100      * The constructor to initialize an AvahiTimeout.
101      *
102      * @param[in]   aTimeout    A pointer to the time after which the callback should be called.
103      * @param[in]   aCallback   The function to be called after timeout.
104      * @param[in]   aContext    A pointer to application-specific context.
105      * @param[in]   aPoller     The Poller this timeout belongs to.
106      *
107      */
108     AvahiTimeout(const struct timeval *aTimeout, AvahiTimeoutCallback aCallback, void *aContext, void *aPoller);
109 };
110
111 namespace otbr {
112
113 namespace Mdns {
114
115 /**
116  * This class implements the AvahiPoll.
117  *
118  */
119 class Poller
120 {
121 public:
122     /**
123      * The constructor to initialize a Poller.
124      *
125      */
126     Poller(void);
127
128     /**
129      * This method updates the fd_set and timeout for mainloop.
130      *
131      * @param[inout]    aReadFdSet      A reference to fd_set for polling read.
132      * @param[inout]    aWriteFdSet     A reference to fd_set for polling write.
133      * @param[inout]    aErrorFdSet     A reference to fd_set for polling error.
134      * @param[inout]    aMaxFd          A reference to the max file descriptor.
135      * @param[inout]    aTimeout        A reference to the timeout.
136      *
137      */
138     void UpdateFdSet(fd_set &aReadFdSet, fd_set &aWriteFdSet, fd_set &aErrorFdSet, int &aMaxFd, timeval &aTimeout);
139
140     /**
141      * This method performs avahi poll processing.
142      *
143      * @param[in]   aReadFdSet   A reference to read file descriptors.
144      * @param[in]   aWriteFdSet  A reference to write file descriptors.
145      * @param[in]   aErrorFdSet  A reference to error file descriptors.
146      *
147      */
148     void Process(const fd_set &aReadFdSet, const fd_set &aWriteFdSet, const fd_set &aErrorFdSet);
149
150     /**
151      * This method returns the AvahiPoll.
152      *
153      * @returns A pointer to the AvahiPoll.
154      *
155      */
156     const AvahiPoll *GetAvahiPoll(void) const { return &mAvahiPoller; }
157
158 private:
159     typedef std::vector<AvahiWatch *>   Watches;
160     typedef std::vector<AvahiTimeout *> Timers;
161
162     static AvahiWatch *    WatchNew(const struct AvahiPoll *aPoller,
163                                     int                     aFd,
164                                     AvahiWatchEvent         aEvent,
165                                     AvahiWatchCallback      aCallback,
166                                     void *                  aContext);
167     AvahiWatch *           WatchNew(int aFd, AvahiWatchEvent aEvent, AvahiWatchCallback aCallback, void *aContext);
168     static void            WatchUpdate(AvahiWatch *aWatch, AvahiWatchEvent aEvent);
169     static AvahiWatchEvent WatchGetEvents(AvahiWatch *aWatch);
170     static void            WatchFree(AvahiWatch *aWatch);
171     void                   WatchFree(AvahiWatch &aWatch);
172     static AvahiTimeout *  TimeoutNew(const AvahiPoll *     aPoller,
173                                       const struct timeval *aTimeout,
174                                       AvahiTimeoutCallback  aCallback,
175                                       void *                aContext);
176     AvahiTimeout *         TimeoutNew(const struct timeval *aTimeout, AvahiTimeoutCallback aCallback, void *aContext);
177     static void            TimeoutUpdate(AvahiTimeout *aTimer, const struct timeval *aTimeout);
178     static void            TimeoutFree(AvahiTimeout *aTimer);
179     void                   TimeoutFree(AvahiTimeout &aTimer);
180
181     Watches   mWatches;
182     Timers    mTimers;
183     AvahiPoll mAvahiPoller;
184 };
185
186 /**
187  * This class implements MDNS service with avahi.
188  *
189  */
190 class PublisherAvahi : public Publisher
191 {
192 public:
193     /**
194      * The constructor to initialize a Publisher.
195      *
196      * @param[in]   aProtocol           The protocol used for publishing. IPv4, IPv6 or both.
197      * @param[in]   aDomain             The domain of the host. nullptr to use default.
198      * @param[in]   aHandler            The function to be called when state changes.
199      * @param[in]   aContext            A pointer to application-specific context.
200      *
201      */
202     PublisherAvahi(int aProtocol, const char *aDomain, StateHandler aHandler, void *aContext);
203
204     ~PublisherAvahi(void) override;
205
206     /**
207      * This method publishes or updates a service.
208      *
209      * @param[in]   aHostName           The name of the host which this service resides on. If NULL is provided,
210      *                                  this service resides on local host and it is the implementation to provide
211      *                                  specific host name. Otherwise, the caller MUST publish the host with method
212      *                                  PublishHost.
213      * @param[in]   aName               The name of this service.
214      * @param[in]   aType               The type of this service.
215      * @param[in]   aPort               The port number of this service.
216      * @param[in]   aTxtList            A list of TXT name/value pairs.
217      *
218      * @retval  OTBR_ERROR_NONE     Successfully published or updated the service.
219      * @retval  OTBR_ERROR_ERRNO    Failed to publish or update the service.
220      *
221      */
222     otbrError PublishService(const char *   aHostName,
223                              uint16_t       aPort,
224                              const char *   aName,
225                              const char *   aType,
226                              const TxtList &aTxtList) override;
227
228     /**
229      * This method un-publishes a service.
230      *
231      * @param[in]   aName               The name of this service.
232      * @param[in]   aType               The type of this service.
233      *
234      * @retval  OTBR_ERROR_NONE     Successfully un-published the service.
235      * @retval  OTBR_ERROR_ERRNO    Failed to un-publish the service.
236      *
237      */
238     otbrError UnpublishService(const char *aName, const char *aType) override;
239
240     /**
241      * This method publishes or updates a host.
242      *
243      * Publishing a host is advertising an AAAA RR for the host name. This method should be called
244      * before a service with non-null host name is published.
245      *
246      * @param[in]  aName           The name of the host.
247      * @param[in]  aAddress        The address of the host.
248      * @param[in]  aAddressLength  The length of @p aAddress.
249      *
250      * @retval  OTBR_ERROR_NONE     Successfully published or updated the host.
251      * @retval  OTBR_ERROR_ERRNO    Failed to publish or update the host.
252      *
253      */
254     otbrError PublishHost(const char *aName, const uint8_t *aAddress, uint8_t aAddressLength) override;
255
256     /**
257      * This method un-publishes a host.
258      *
259      * @param[in]  aName  A host name.
260      *
261      * @retval  OTBR_ERROR_NONE     Successfully un-published the host.
262      * @retval  OTBR_ERROR_ERRNO    Failed to un-publish the host.
263      *
264      * @note  All services reside on this host should be un-published by UnpublishService.
265      *
266      */
267     otbrError UnpublishHost(const char *aName) override;
268
269     /**
270      * This method starts the MDNS service.
271      *
272      * @retval OTBR_ERROR_NONE  Successfully started MDNS service;
273      * @retval OTBR_ERROR_MDNS  Failed to start MDNS service.
274      *
275      */
276     otbrError Start(void) override;
277
278     /**
279      * This method checks if publisher has been started.
280      *
281      * @retval true     Already started.
282      * @retval false    Not started.
283      *
284      */
285     bool IsStarted(void) const override;
286
287     /**
288      * This method stops the MDNS service.
289      *
290      */
291     void Stop(void) override;
292
293     /**
294      * This method performs avahi poll processing.
295      *
296      * @param[in]   aReadFdSet          A reference to read file descriptors.
297      * @param[in]   aWriteFdSet         A reference to write file descriptors.
298      * @param[in]   aErrorFdSet         A reference to error file descriptors.
299      *
300      */
301     void Process(const fd_set &aReadFdSet, const fd_set &aWriteFdSet, const fd_set &aErrorFdSet) override;
302
303     /**
304      * This method updates the fd_set and timeout for mainloop.
305      *
306      * @param[inout]    aReadFdSet      A reference to fd_set for polling read.
307      * @param[inout]    aWriteFdSet     A reference to fd_set for polling write.
308      * @param[inout]    aErrorFdSet     A reference to fd_set for polling error.
309      * @param[inout]    aMaxFd          A reference to the max file descriptor.
310      * @param[inout]    aTimeout        A reference to the timeout.
311      *
312      */
313     void UpdateFdSet(fd_set & aReadFdSet,
314                      fd_set & aWriteFdSet,
315                      fd_set & aErrorFdSet,
316                      int &    aMaxFd,
317                      timeval &aTimeout) override;
318
319 private:
320     enum
321     {
322         kMaxSizeOfTxtRecord   = 128,
323         kMaxSizeOfServiceName = AVAHI_LABEL_MAX,
324         kMaxSizeOfHost        = AVAHI_LABEL_MAX,
325         kMaxSizeOfDomain      = AVAHI_LABEL_MAX,
326         kMaxSizeOfServiceType = AVAHI_LABEL_MAX,
327     };
328
329     struct Service
330     {
331         char     mName[kMaxSizeOfServiceName];
332         char     mType[kMaxSizeOfServiceType];
333         uint16_t mPort;
334     };
335
336     typedef std::vector<Service> Services;
337
338     static void HandleClientState(AvahiClient *aClient, AvahiClientState aState, void *aContext);
339     void        HandleClientState(AvahiClient *aClient, AvahiClientState aState);
340
341     void        CreateGroup(AvahiClient *aClient);
342     static void HandleGroupState(AvahiEntryGroup *aGroup, AvahiEntryGroupState aState, void *aContext);
343     void        HandleGroupState(AvahiEntryGroup *aGroup, AvahiEntryGroupState aState);
344
345     Services         mServices;
346     AvahiClient *    mClient;
347     AvahiEntryGroup *mGroup;
348     Poller           mPoller;
349     int              mProtocol;
350     const char *     mDomain;
351     State            mState;
352     StateHandler     mStateHandler;
353     void *           mContext;
354 };
355
356 } // namespace Mdns
357
358 } // namespace otbr
359
360 /**
361  * @}
362  */
363 #endif // OTBR_AGENT_MDNS_AVAHI_HPP_