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