• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2023, 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 definitions for DNS-SD module.
32  */
33 
34 #ifndef DNSSD_HPP_
35 #define DNSSD_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE || OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
40 
41 #if !OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
42 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE && OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
43 #error "Must enable either `PLATFORM_DNSSD_ENABLE` or `MULTICAST_DNS_ENABLE` and not both."
44 #endif
45 #else
46 #if !OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE || !OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
47 #error "`PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION` requires both `PLATFORM_DNSSD_ENABLE` or `MULTICAST_DNS_ENABLE`.".
48 #endif
49 #endif // !OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
50 
51 #include <openthread/platform/dnssd.h>
52 
53 #include "common/clearable.hpp"
54 #include "common/locator.hpp"
55 #include "common/non_copyable.hpp"
56 #include "net/ip6_address.hpp"
57 
58 namespace ot {
59 
60 /**
61  * @addtogroup core-dns
62  *
63  * @brief
64  *   This module includes definitions for DNS-SD (mDNS) APIs used by other modules in OT (e.g. advertising proxy).
65  *
66  *   The DNS-SD is implemented either using the native mDNS module in OpenThread or using `otPlatDnssd` platform
67  *   APIs (delegating the DNS-SD implementation to platform layer).
68  *
69  * @{
70  */
71 
72 extern "C" void otPlatDnssdStateHandleStateChange(otInstance *aInstance);
73 
74 /**
75  * Represents DNS-SD module.
76  */
77 class Dnssd : public InstanceLocator, private NonCopyable
78 {
79     friend void otPlatDnssdStateHandleStateChange(otInstance *aInstance);
80 
81 public:
82     /**
83      * Represents state of DNS-SD platform.
84      */
85     enum State : uint8_t
86     {
87         kStopped = OT_PLAT_DNSSD_STOPPED, ///< Stopped and unable to register any service or host.
88         kReady   = OT_PLAT_DNSSD_READY    ///< Running and ready to register service or host.
89     };
90 
91     typedef otPlatDnssdRequestId        RequestId;        ///< A request ID.
92     typedef otPlatDnssdRegisterCallback RegisterCallback; ///< The registration request callback
93     typedef otPlatDnssdBrowseCallback   BrowseCallback;   ///< Browser callback.
94     typedef otPlatDnssdSrvCallback      SrvCallback;      ///< SRV callback.
95     typedef otPlatDnssdTxtCallback      TxtCallback;      ///< TXT callback.
96     typedef otPlatDnssdAddressCallback  AddressCallback;  ///< Address callback
97     typedef otPlatDnssdBrowseResult     BrowseResult;     ///< Browser result.
98     typedef otPlatDnssdSrvResult        SrvResult;        ///< SRV result.
99     typedef otPlatDnssdTxtResult        TxtResult;        ///< TXT result.
100     typedef otPlatDnssdAddressResult    AddressResult;    ///< Address result.
101     typedef otPlatDnssdAddressAndTtl    AddressAndTtl;    ///< Address and TTL.
102 
103     class Host : public otPlatDnssdHost, public Clearable<Host> ///< Host information.
104     {
105     };
106 
107     class Service : public otPlatDnssdService, public Clearable<Service> ///< Service information.
108     {
109     };
110 
111     class Key : public otPlatDnssdKey, public Clearable<Key> ///< Key information
112     {
113     };
114 
115     class Browser : public otPlatDnssdBrowser, public Clearable<Browser> ///< Browser.
116     {
117     };
118 
119     class SrvResolver : public otPlatDnssdSrvResolver, public Clearable<SrvResolver> ///< SRV resolver.
120     {
121     };
122 
123     class TxtResolver : public otPlatDnssdTxtResolver, public Clearable<TxtResolver> ///< TXT resolver.
124     {
125     };
126 
127     class AddressResolver : public otPlatDnssdAddressResolver, public Clearable<AddressResolver> ///< Address resolver.
128     {
129     };
130 
131     /**
132      * Represents a range of `RequestId` values.
133      *
134      * The range is stored using start and end ID values. The implementation handles the case when ID values roll over.
135      */
136     struct RequestIdRange : public Clearable<RequestIdRange>
137     {
138         /**
139          * Initializes a range as empty.
140          */
RequestIdRangeot::Dnssd::RequestIdRange141         RequestIdRange(void)
142             : mStart(0)
143             , mEnd(0)
144         {
145         }
146 
147         /**
148          * Adds a request ID to the range.
149          *
150          * @param[in] aId   The ID to add to the range.
151          */
152         void Add(RequestId aId);
153 
154         /**
155          * Removes a request ID from the range.
156          *
157          * @param[in] aId   The ID to remove from the range.
158          */
159         void Remove(RequestId aId);
160 
161         /**
162          * Indicates whether or not a given ID is contained within the range.
163          *
164          * @param[in] aId   The ID to check.
165          *
166          * @retval TRUE  The @p aID is contained within the range.
167          * @retval FALSE The @p aId is not contained within the range.
168          */
169         bool Contains(RequestId aId) const;
170 
171         /**
172          * Indicates whether or not the range is empty.
173          *
174          * @retval TRUE  The range is empty.
175          * @retval FALSE The range is not empty.
176          */
IsEmptyot::Dnssd::RequestIdRange177         bool IsEmpty(void) const { return (mStart == mEnd); }
178 
179     private:
180         // The range is represented as all `RequestId` values from
181         // `mStart` up to, but not including, `mEnd`. It uses serial
182         // number arithmetic logic when comparing `RequestId` values,
183         // so `Contains()` and other methods work correctly even when
184         // the ID value rolls over.
185 
186         RequestId mStart;
187         RequestId mEnd;
188     };
189 
190     /**
191      * Initializes `Dnssd` object.
192      *
193      * @param[in]  aInstance  The OpenThread instance.
194      */
195     explicit Dnssd(Instance &aInstance);
196 
197     /**
198      * Gets the current state of DNS-SD platform module.
199      *
200      * @returns The current state of DNS-SD platform.
201      */
202     State GetState(void) const;
203 
204     /**
205      * Indicates whether or not DNS-SD platform is ready (in `kReady` state).
206      *
207      * @retval TRUE   The DNS-SD platform is ready.
208      * @retval FALSE  The DNS-SD platform is not ready.
209      */
IsReady(void) const210     bool IsReady(void) const { return GetState() == kReady; }
211 
212     /**
213      * Registers or updates a service on the infrastructure network's DNS-SD module.
214      *
215      * Refer to the documentation for `otPlatDnssdRegisterService()`, for a more detailed description of the behavior
216      * of this method.
217      *
218      * @param[in] aService     Information about service to unregister.
219      * @param[in] aRequestId   The ID associated with this request.
220      * @param[in] aCallback    The callback function pointer to report the outcome (may be `nullptr`).
221      */
222     void RegisterService(const Service &aService, RequestId aRequestId, RegisterCallback aCallback);
223 
224     /**
225      * Unregisters a service on the infrastructure network's DNS-SD module.
226      *
227      * Refer to the documentation for `otPlatDnssdUnregisterService()`, for a more detailed description of the behavior
228      * of this method.
229      *
230      * @param[in] aService      Information about service to unregister.
231      * @param[in] aRequestId    The ID associated with this request.
232      * @param[in] aCallback     The callback function pointer to report the outcome (may be `nullptr`).
233      */
234     void UnregisterService(const Service &aService, RequestId aRequestId, RegisterCallback aCallback);
235 
236     /**
237      * Registers or updates a host on the infrastructure network's DNS-SD module.
238      *
239      * Refer to the documentation for `otPlatDnssdRegisterHost()`, for a more detailed description of the behavior
240      * of this method.
241      *
242      * @param[in] aHost         Information about host to register.
243      * @param[in] aRequestId    The ID associated with this request.
244      * @param[in] aCallback     The callback function pointer to report the outcome (may be `nullptr`).
245      */
246     void RegisterHost(const Host &aHost, RequestId aRequestId, RegisterCallback aCallback);
247 
248     /**
249      * Unregisters a host on the infrastructure network's DNS-SD module.
250      *
251      * Refer to the documentation for `otPlatDnssdUnregisterHost()`, for a more detailed description of the behavior
252      * of this method.
253      *
254      * @param[in] aHost         Information about the host to unregister.
255      * @param[in] aRequestId    The ID associated with this request.
256      * @param[in] aCallback     The callback function pointer to report the outcome (may be NULL if no callback needed).
257      */
258     void UnregisterHost(const Host &aHost, RequestId aRequestId, RegisterCallback aCallback);
259 
260     /**
261      * Registers or updates a key record on the infrastructure network's DNS-SD module.
262      *
263      * Refer to the documentation for `otPlatDnssdRegisterKey()`, for a more detailed description of the behavior
264      * of this method.
265      *
266      * @param[in] aKey          Information about the key to register.
267      * @param[in] aRequestId    The ID associated with this request.
268      * @param[in] aCallback     The callback function pointer to report the outcome (may be `nullptr`).
269      */
270     void RegisterKey(const Key &aKey, RequestId aRequestId, RegisterCallback aCallback);
271 
272     /**
273      * Unregisters a key record on the infrastructure network's DNS-SD module.
274      *
275      * Refer to the documentation for `otPlatDnssdUnregisterKey()`, for a more detailed description of the behavior
276      * of this method.
277      *
278      * @param[in] aKey          Information about the key to unregister.
279      * @param[in] aRequestId    The ID associated with this request.
280      * @param[in] aCallback     The callback function pointer to report the outcome (may be NULL if no callback needed).
281      */
282     void UnregisterKey(const Key &aKey, RequestId aRequestId, RegisterCallback aCallback);
283 
284     /**
285      * Starts a service browser.
286      *
287      * Refer to the documentation for `otPlatDnssdStartBrowser()` for a more detailed description of the behavior
288      * of this method.
289      *
290      * @param[in] aBrowser    The browser to be started.
291      */
292     void StartBrowser(const Browser &aBrowser);
293 
294     /**
295      * Stops a service browser.
296      *
297      * Refer to the documentation for `otPlatDnssdStopBrowser()` for a more detailed description of the behavior
298      * of this method.
299      *
300      * @param[in] aBrowser    The browser to stop.
301      */
302     void StopBrowser(const Browser &aBrowser);
303 
304     /**
305      * Starts an SRV record resolver.
306      *
307      * Refer to the documentation for `otPlatDnssdStartSrvResolver()` for a more detailed description of the behavior
308      * of this method.
309      *
310      * @param[in] aResolver    The resolver to be started.
311      */
312     void StartSrvResolver(const SrvResolver &aResolver);
313 
314     /**
315      * Stops an SRV record resolver.
316      *
317      * Refer to the documentation for `otPlatDnssdStopSrvResolver()` for a more detailed description of the behavior
318      * of this method.
319      *
320      * @param[in] aResolver    The resolver to stop.
321      */
322     void StopSrvResolver(const SrvResolver &aResolver);
323 
324     /**
325      * Starts a TXT record resolver.
326      *
327      * Refer to the documentation for `otPlatDnssdStartTxtResolver()` for a more detailed description of the behavior
328      * of this method.
329      *
330      * @param[in] aResolver    The resolver to be started.
331      */
332     void StartTxtResolver(const TxtResolver &aResolver);
333 
334     /**
335      * Stops a TXT record resolver.
336      *
337      * Refer to the documentation for `otPlatDnssdStopTxtResolver()` for a more detailed description of the behavior
338      * of this method.
339      *
340      * @param[in] aResolver    The resolver to stop.
341      */
342     void StopTxtResolver(const TxtResolver &aResolver);
343 
344     /**
345      * Starts an IPv6 address resolver.
346      *
347      * Refer to the documentation for `otPlatDnssdStartIp6AddressResolver()` for a more detailed description of the
348      * behavior of this method.
349      *
350      * @param[in] aResolver    The resolver to be started.
351      */
352     void StartIp6AddressResolver(const AddressResolver &aResolver);
353 
354     /**
355      * Stops an IPv6 address resolver.
356      *
357      * Refer to the documentation for `otPlatDnssdStopIp6AddressResolver()` for a more detailed description of the
358      * behavior of this method.
359      *
360      * @param[in] aResolver    The resolver to stop.
361      */
362     void StopIp6AddressResolver(const AddressResolver &aResolver);
363 
364     /**
365      * Starts an IPv4 address resolver.
366      *
367      * Refer to the documentation for `otPlatDnssdStartIp4AddressResolver()` for a more detailed description of the
368      * behavior of this method.
369      *
370      * @param[in] aResolver    The resolver to be started.
371      */
372     void StartIp4AddressResolver(const AddressResolver &aResolver);
373 
374     /**
375      * Stops an IPv4 address resolver.
376      *
377      * Refer to the documentation for `otPlatDnssdStopIp4AddressResolver()` for a more detailed description of the
378      * behavior of this method.
379      *
380      * @param[in] aResolver    The resolver to stop.
381      */
382     void StopIp4AddressResolver(const AddressResolver &aResolver);
383 
384 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
385     /**
386      * Handles native mDNS state change.
387      *
388      * This is used to notify `Dnssd` when `Multicast::Dns::Core` gets enabled or disabled.
389      */
390     void HandleMdnsCoreStateChange(void);
391 #endif
392 
393 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
394     /**
395      * Selects whether to use the native mDNS or the platform `otPlatDnssd` APIs.
396      *
397      * @param[in] aUseMdns    TRUE to use the native mDNS module, FALSE to use platform APIs.
398      */
SetUseNativeMdns(bool aUseMdns)399     void SetUseNativeMdns(bool aUseMdns) { mUseNativeMdns = aUseMdns; }
400 
401     /**
402      * Indicates whether the `Dnssd` is using the native mDNS or the platform `otPlatDnssd` APIs.
403      *
404      * @retval TRUE    `Dnssd` is using the native mDSN module.
405      * @retval FALSE   `Dnssd` is using the platform `otPlatDnssd` APIs.
406      */
ShouldUseNativeMdns(void) const407     bool ShouldUseNativeMdns(void) const { return mUseNativeMdns; }
408 #endif
409 
410 private:
411     void HandleStateChange(void);
412 
413 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
414     bool mUseNativeMdns;
415 #endif
416 };
417 
418 /**
419  * @}
420  */
421 
422 DefineMapEnum(otPlatDnssdState, Dnssd::State);
423 DefineCoreType(otPlatDnssdService, Dnssd::Service);
424 DefineCoreType(otPlatDnssdHost, Dnssd::Host);
425 DefineCoreType(otPlatDnssdKey, Dnssd::Key);
426 
427 } // namespace ot
428 
429 #endif // OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE || OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
430 
431 #endif // DNSSD_HPP_
432