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