2 * Copyright (c) 2017, The OpenThread Authors.
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.
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.
31 * This file includes definition for MDNS service based on avahi.
34 #ifndef OTBR_AGENT_MDNS_AVAHI_HPP_
35 #define OTBR_AGENT_MDNS_AVAHI_HPP_
39 #include <avahi-client/client.h>
40 #include <avahi-client/publish.h>
41 #include <avahi-common/domain.h>
42 #include <avahi-common/watch.h>
47 * @addtogroup border-router-mdns
50 * This module includes definition for avahi-based MDNS service.
56 * This structure implements AvahiWatch.
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.
69 * The constructor to initialize an Avahi watch.
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.
78 AvahiWatch(int aFd, AvahiWatchEvent aEvents, AvahiWatchCallback aCallback, void *aContext, void *aPoller)
81 , mCallback(aCallback)
89 * This structure implements the AvahiTimeout.
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.
100 * The constructor to initialize an AvahiTimeout.
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.
108 AvahiTimeout(const struct timeval *aTimeout, AvahiTimeoutCallback aCallback, void *aContext, void *aPoller);
116 * This class implements the AvahiPoll.
123 * The constructor to initialize a Poller.
129 * This method updates the fd_set and timeout for mainloop.
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.
138 void UpdateFdSet(fd_set &aReadFdSet, fd_set &aWriteFdSet, fd_set &aErrorFdSet, int &aMaxFd, timeval &aTimeout);
141 * This method performs avahi poll processing.
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.
148 void Process(const fd_set &aReadFdSet, const fd_set &aWriteFdSet, const fd_set &aErrorFdSet);
151 * This method returns the AvahiPoll.
153 * @returns A pointer to the AvahiPoll.
156 const AvahiPoll *GetAvahiPoll(void) const { return &mAvahiPoller; }
159 typedef std::vector<AvahiWatch *> Watches;
160 typedef std::vector<AvahiTimeout *> Timers;
162 static AvahiWatch * WatchNew(const struct AvahiPoll *aPoller,
164 AvahiWatchEvent aEvent,
165 AvahiWatchCallback aCallback,
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,
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);
183 AvahiPoll mAvahiPoller;
187 * This class implements MDNS service with avahi.
190 class PublisherAvahi : public Publisher
194 * The constructor to initialize a Publisher.
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.
202 PublisherAvahi(int aProtocol, const char *aDomain, StateHandler aHandler, void *aContext);
204 ~PublisherAvahi(void) override;
207 * This method publishes or updates a service.
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
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.
218 * @retval OTBR_ERROR_NONE Successfully published or updated the service.
219 * @retval OTBR_ERROR_ERRNO Failed to publish or update the service.
222 otbrError PublishService(const char * aHostName,
226 const TxtList &aTxtList) override;
229 * This method un-publishes a service.
231 * @param[in] aName The name of this service.
232 * @param[in] aType The type of this service.
234 * @retval OTBR_ERROR_NONE Successfully un-published the service.
235 * @retval OTBR_ERROR_ERRNO Failed to un-publish the service.
238 otbrError UnpublishService(const char *aName, const char *aType) override;
241 * This method publishes or updates a host.
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.
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.
250 * @retval OTBR_ERROR_NONE Successfully published or updated the host.
251 * @retval OTBR_ERROR_ERRNO Failed to publish or update the host.
254 otbrError PublishHost(const char *aName, const uint8_t *aAddress, uint8_t aAddressLength) override;
257 * This method un-publishes a host.
259 * @param[in] aName A host name.
261 * @retval OTBR_ERROR_NONE Successfully un-published the host.
262 * @retval OTBR_ERROR_ERRNO Failed to un-publish the host.
264 * @note All services reside on this host should be un-published by UnpublishService.
267 otbrError UnpublishHost(const char *aName) override;
270 * This method starts the MDNS service.
272 * @retval OTBR_ERROR_NONE Successfully started MDNS service;
273 * @retval OTBR_ERROR_MDNS Failed to start MDNS service.
276 otbrError Start(void) override;
279 * This method checks if publisher has been started.
281 * @retval true Already started.
282 * @retval false Not started.
285 bool IsStarted(void) const override;
288 * This method stops the MDNS service.
291 void Stop(void) override;
294 * This method performs avahi poll processing.
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.
301 void Process(const fd_set &aReadFdSet, const fd_set &aWriteFdSet, const fd_set &aErrorFdSet) override;
304 * This method updates the fd_set and timeout for mainloop.
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.
313 void UpdateFdSet(fd_set & aReadFdSet,
314 fd_set & aWriteFdSet,
315 fd_set & aErrorFdSet,
317 timeval &aTimeout) override;
322 kMaxSizeOfTxtRecord = 128,
323 kMaxSizeOfServiceName = AVAHI_LABEL_MAX,
324 kMaxSizeOfHost = AVAHI_LABEL_MAX,
325 kMaxSizeOfDomain = AVAHI_LABEL_MAX,
326 kMaxSizeOfServiceType = AVAHI_LABEL_MAX,
331 char mName[kMaxSizeOfServiceName];
332 char mType[kMaxSizeOfServiceType];
336 typedef std::vector<Service> Services;
338 static void HandleClientState(AvahiClient *aClient, AvahiClientState aState, void *aContext);
339 void HandleClientState(AvahiClient *aClient, AvahiClientState aState);
341 void CreateGroup(AvahiClient *aClient);
342 static void HandleGroupState(AvahiEntryGroup *aGroup, AvahiEntryGroupState aState, void *aContext);
343 void HandleGroupState(AvahiEntryGroup *aGroup, AvahiEntryGroupState aState);
346 AvahiClient * mClient;
347 AvahiEntryGroup *mGroup;
350 const char * mDomain;
352 StateHandler mStateHandler;
363 #endif // OTBR_AGENT_MDNS_AVAHI_HPP_