blob: e7a2a7f0b0fffcb2afe7192b5c05abee1270ec04 [file] [log] [blame]
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief
* This file includes the platform abstraction for DNS-SD (e.g., mDNS) on the infrastructure network.
*
*/
#ifndef OPENTHREAD_PLATFORM_DNSSD_H_
#define OPENTHREAD_PLATFORM_DNSSD_H_
#include <stdint.h>
#include <openthread/dns.h>
#include <openthread/error.h>
#include <openthread/instance.h>
#include <openthread/ip6.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup plat-dns-sd
*
* @brief
* This module includes the platform abstraction for DNS-SD (e.g., mDNS) on the infrastructure network.
*
* @{
*
* The DNS-SD platform APIs are used only when `OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE` is enabled.
*
*/
/**
* Represents the state of the DNS-SD platform.
*
*/
typedef enum otPlatDnssdState
{
OT_PLAT_DNSSD_STOPPED, ///< Stopped and unable to register any service or host.
OT_PLAT_DNSSD_READY, ///< Running and ready to register service or host.
} otPlatDnssdState;
/**
* Represents a request ID for registering/unregistering a service or host.
*
*/
typedef uint32_t otPlatDnssdRequestId;
/**
* Represents the callback function used when registering/unregistering a host or service.
*
* See `otPlatDnssdRegisterService()`, `otPlatDnssdUnregisterService()`, `otPlatDnssdRegisterHost()`, and
* `otPlatDnssdUnregisterHost()` for more details about when to invoke the callback and the `aError` values that can
* be returned in each case.
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aRequestId The request ID.
* @param[in] aError Error indicating the outcome of request.
*
*/
typedef void (*otPlatDnssdRegisterCallback)(otInstance *aInstance, otPlatDnssdRequestId aRequestId, otError aError);
/**
* Represents a DNS-SD service.
*
* See `otPlatDnssdRegisterService()`, `otPlatDnssdUnregisterService()` for more details about fields in each case.
*
*/
typedef struct otPlatDnssdService
{
const char *mHostName; ///< The host name (does not include domain name).
const char *mServiceInstance; ///< The service instance name label (not the full name).
const char *mServiceType; ///< The service type (e.g., "_mt._udp", does not include domain name).
const char *const *mSubTypeLabels; ///< Array of sub-type labels (can be NULL if no label).
uint16_t mSubTypeLabelsLength; ///< Length of array of sub-type labels.
const uint8_t *mTxtData; ///< Encoded TXT data bytes.
uint16_t mTxtDataLength; ///< Length of TXT data.
uint16_t mPort; ///< The service port number.
uint16_t mPriority; ///< The service priority.
uint16_t mWeight; ///< The service weight.
uint32_t mTtl; ///< The service TTL in seconds.
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
} otPlatDnssdService;
/**
* Represents a DNS-SD host.
*
* See `otPlatDnssdRegisterHost()`, `otPlatDnssdUnregisterHost()` for more details about fields in each case.
*
*/
typedef struct otPlatDnssdHost
{
const char *mHostName; ///< The host name (does not include domain name).
const otIp6Address *mAddresses; ///< Array of IPv6 host addresses.
uint16_t mAddressesLength; ///< Number of entries in @p mAddresses array.
uint32_t mTtl; ///< The host TTL in seconds.
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
} otPlatDnssdHost;
/**
* Represents a DNS-SD key record.
*
* See `otPlatDnssdRegisterKey()`, `otPlatDnssdUnregisterKey()` for more details about fields in each case.
*
*/
typedef struct otPlatDnssdKey
{
const char *mName; ///< A host or a service instance name (does not include domain name).
const char *mServiceType; ///< The service type if key is for a service (does not include domain name).
const uint8_t *mKeyData; ///< Byte array containing the key record data.
uint16_t mKeyDataLength; ///< Length of @p mKeyData in bytes.
uint16_t mClass; ///< The resource record class.
uint32_t mTtl; ///< The TTL in seconds.
uint32_t mInfraIfIndex; ///< The infrastructure network interface index.
} otPlatDnssdKey;
/**
* Callback to notify state changes of the DNS-SD platform.
*
* The OpenThread stack will call `otPlatDnssdGetState()` (from this callback or later) to get the new state. The
* platform MUST therefore ensure that the returned state from `otPlatDnssdGetState()` is updated before calling this.
*
* @param[in] aInstance The OpenThread instance structure.
*
*/
extern void otPlatDnssdStateHandleStateChange(otInstance *aInstance);
/**
* Gets the current state of the DNS-SD module.
*
* The platform MUST notify the OpenThread stack whenever its state gets changed by invoking
* `otPlatDnssdStateHandleStateChange()`.
*
* @param[in] aInstance The OpenThread instance.
*
* @returns The current state of the DNS-SD module.
*
*/
otPlatDnssdState otPlatDnssdGetState(otInstance *aInstance);
/**
* Registers or updates a service on the infrastructure network's DNS-SD module.
*
* The @p aService and all its contained information (strings and buffers) are only valid during this call. The
* platform MUST save a copy of the information if it wants to retain the information after returning from this
* function.
*
* The fields in @p aService follow these rules:
*
* - The `mServiceInstance` and `mServiceType` fields specify the service instance label and service type name,
* respectively. They are never NULL.
* - The `mHostName` field specifies the host name of the service if it is not NULL. Otherwise, if it is NULL, it
* indicates that this service is for the device itself and leaves the host name selection to DNS-SD platform.
* - The `mSubTypeLabels` is an array of strings representing sub-types associated with the service. It can be NULL
* if there are no sub-types. Otherwise, the array length is specified by `mSubTypeLabelsLength`.
* - The `mTxtData` and `mTxtDataLength` fields specify the encoded TXT data.
* - The `mPort`, `mWeight`, and `mPriority` fields specify the service's parameters (as specified in DNS SRV record).
* - The `mTtl` field specifies the TTL if non-zero. If zero, the platform can choose the TTL to use.
* - The `mInfraIfIndex` field, if non-zero, specifies the infrastructure network interface index to use for this
* request. If zero, the platform implementation can decided the interface.
*
* When the `mHostName` field in @p aService is not NULL (indicating that this registration is on behalf of another
* host), the OpenThread stack will ensure that `otPlatDnssdRegisterHost()` is also called for the same host before any
* service registration requests for the same host.
*
* Once the registration request is finished, either successfully or failed, the platform reports the outcome by
* invoking the @p aCallback and passing the same @p aRequestId in the callback. The @p aCallback function pointer can
* be NULL, which indicates that the OpenThread stack does not need to be notified of the outcome of the request.
* If the outcome is determined, the platform implementation may invoke the @p aCallback before returning from this
* function. The OpenThread stack will ensure to handle such a situation.
*
* On success, the @p aCallback MUST be called (if non-NULL) with `OT_ERROR_NONE` as the `aError` input parameter. If
* the registration causes a name conflict on DNS-SD domain (the service instance name is already claimed by another
* host), the `OT_ERROR_DUPLICATED` error MUST be used. The platform implementation can use other `OT_ERROR` types for
* other types of errors.
*
* The platform implementation MUST not assume that the @p aRequestId used in subsequent requests will be different.
* OpenThread may reuse the same request ID again for a different request.
*
* The OpenThread stack will not register the same service (with no changes) that was registered successfully earlier.
* Therefore, the platform implementation does not need to check for duplicate/same service and can assume that calls
* to this function are either registering a new entry or changing some parameter in a previously registered item. As
* a result, these changes always need to be synced on the infrastructure DNS-SD module.
*
* The OpenThread stack does not require the platform implementation to always invoke the @p aCallback function.
* The OpenThread stack has its own mechanism to time out an aged request with no response. This relaxes the
* requirement for platform implementations.
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aService Information about the service to register.
* @param[in] aRequestId The ID associated with this request.
* @param[in] aCallback The callback function pointer to report the outcome (may be NULL if no callback needed).
*
*/
void otPlatDnssdRegisterService(otInstance *aInstance,
const otPlatDnssdService *aService,
otPlatDnssdRequestId aRequestId,
otPlatDnssdRegisterCallback aCallback);
/**
* Unregisters a service on the infrastructure network's DNS-SD module.
*
* The @p aService and all its contained information (strings and buffers) are only valid during this call. The
* platform MUST save a copy of the information if it wants to retain the information after returning from this
* function.
*
* The fields in @p aService follow these rules:
*
* - The `mServiceInstance` and `mServiceType` fields specify the service instance label and service type name,
* respectively. They are never NULL.
* - The `mHostName` field specifies the host name of the service if it is not NULL. Otherwise, if it is NULL, it
* indicates that this service is for the device itself and leaves the host name selection to DNS-SD platform.
* - The `mInfraIfIndex` field, if non-zero, specifies the infrastructure network interface index to use for this
* request. If zero, the platform implementation can decided the interface.
* - The rest of the fields in @p aService structure MUST be ignored in `otPlatDnssdUnregisterService()` call and may
* be set to zero by the OpenThread stack.
*
* Regarding the invocation of the @p aCallback and the reuse of the @p aRequestId, this function follows the same
* rules as described in `otPlatDnssdRegisterService()`.
*
* The OpenThread stack may request the unregistration of a service that was not previously registered, and the
* platform implementation MUST handle this case. In such a case, the platform can use either `OT_ERROR_NOT_FOUND` to
* indicate that there was no such registration, or `OT_ERROR_NONE` when invoking the @p aCallback function. The
* OpenThread stack will handle either case correctly.
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aService Information about the service to unregister.
* @param[in] aRequestId The ID associated with this request.
* @param[in] aCallback The callback function pointer to report the outcome (may be NULL if no callback needed).
*
*/
void otPlatDnssdUnregisterService(otInstance *aInstance,
const otPlatDnssdService *aService,
otPlatDnssdRequestId aRequestId,
otPlatDnssdRegisterCallback aCallback);
/**
* Registers or updates a host on the infrastructure network's DNS-SD module.
*
* The @p aHost and all its contained information (strings and arrays) are only valid during this call. The
* platform MUST save a copy of the information if it wants to retain the information after returning from this
* function.
*
* The fields in @p aHost follow these rules:
*
* - The `mHostName` field specifies the host name to register. It is never NULL.
* - The `mAddresses` field is an array of IPv6 addresses to register with the host. `mAddressesLength` field provides
* the number of entries in `mAddresses` array. The platform implementation MUST not filter or remove any of
* addresses in the list.
* The OpenThread stack will already ensure that the given addresses are externally reachable. For example, when
* registering host from an SRP registration, link-local or mesh-local addresses associated with the host which are
* intended for use within Thread mesh are not included in `mAddresses` array passed to this API. The `mAddresses`
* array can be empty with zero `mAddressesLength`. In such a case, the platform MUST stop advertising any addresses
* for this host name on the infrastructure DNS-SD.
* - The `mTtl` field specifies the TTL if non-zero. If zero, the platform can choose the TTL to use.
* - The `mInfraIfIndex` field, if non-zero, specifies the infrastructure network interface index to use for this
* request. If zero, the platform implementation can decided the interface.
*
* Regarding the invocation of the @p aCallback and the reuse of the @p aRequestId, this function follows the same
* rules as described in `otPlatDnssdRegisterService()`.
*
* The OpenThread stack will not register the same host (with no changes) that was registered successfully earlier.
* Therefore, the platform implementation does not need to check for duplicate/same host and can assume that calls
* to this function are either registering a new entry or changing some parameter in a previously registered item. As
* a result, these changes always need to be synced on the infrastructure DNS-SD module.
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aHost Information about the host to register.
* @param[in] aRequestId The ID associated with this request.
* @param[in] aCallback The callback function pointer to report the outcome (may be NULL if no callback needed).
*
*/
void otPlatDnssdRegisterHost(otInstance *aInstance,
const otPlatDnssdHost *aHost,
otPlatDnssdRequestId aRequestId,
otPlatDnssdRegisterCallback aCallback);
/**
* Unregisters a host on the infrastructure network's DNS-SD module.
*
* The @p aHost and all its contained information (strings and arrays) are only valid during this call. The
* platform MUST save a copy of the information if it wants to retain the information after returning from this
* function.
*
* The fields in @p aHost follow these rules:
*
* - The `mHostName` field specifies the host name to unregister. It is never NULL.
* - The `mInfraIfIndex` field, if non-zero, specifies the infrastructure network interface index to use for this
* request. If zero, the platform implementation can decided the interface.
* - The rest of the fields in @p aHost structure MUST be ignored in `otPlatDnssdUnregisterHost()` call and may
* be set to zero by the OpenThread stack.
*
* Regarding the invocation of the @p aCallback and the reuse of the @p aRequestId, this function follows the same
* rules as described in `otPlatDnssdRegisterService()`.
*
* The OpenThread stack may request the unregistration of a host that was not previously registered, and the platform
* implementation MUST handle this case. In such a case, the platform can use either `OT_ERROR_NOT_FOUND` to indicate
* that there was no such registration, or `OT_ERROR_NONE` when invoking the @p aCallback function. OpenThread stack
* will handle either case correctly.
*
* When unregistering a host, the OpenThread stack will also unregister any previously registered services
* associated with the same host (by calling `otPlatDnssdUnregisterService()`). However, the platform implementation
* MAY assume that unregistering a host also unregisters all its associated services.
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aHost Information about the host to unregister.
* @param[in] aRequestId The ID associated with this request.
* @param[in] aCallback The callback function pointer to report the outcome (may be NULL if no callback needed).
*
*/
void otPlatDnssdUnregisterHost(otInstance *aInstance,
const otPlatDnssdHost *aHost,
otPlatDnssdRequestId aRequestId,
otPlatDnssdRegisterCallback aCallback);
/**
* Registers or updates a key record on the infrastructure network's DNS-SD module.
*
* The @p aKey and all its contained information (strings and arrays) are only valid during this call. The
* platform MUST save a copy of the information if it wants to retain the information after returning from this
* function.
*
* The fields in @p aKey follow these rules:
*
* - If the key is associated with a host, `mName` field specifies the host name and `mServiceType` will be NULL.
* - If the key is associated with a service, `mName` field specifies the service instance label and `mServiceType`
* field specifies the service type. In this case the DNS name for key record is `{mName}.{mServiceTye}`.
* - The `mKeyData` field contains the key record's data with `mKeyDataLength` as its length in byes. It is never NULL.
* - The `mClass` fields specifies the resource record class to use when registering key record.
* - The `mTtl` field specifies the TTL if non-zero. If zero, the platform can choose the TTL to use.
* - The `mInfraIfIndex` field, if non-zero, specifies the infrastructure network interface index to use for this
* request. If zero, the platform implementation can decided the interface.
*
* Regarding the invocation of the @p aCallback and the reuse of the @p aRequestId, this function follows the same
* rules as described in `otPlatDnssdRegisterService()`.
*
* The OpenThread stack will not register the same key (with no changes) that was registered successfully earlier.
* Therefore, the platform implementation does not need to check for duplicate/same name and can assume that calls
* to this function are either registering a new key or changing the key data in a previously registered one. As
* a result, these changes always need to be synced on the infrastructure DNS-SD module.
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aHost Information about the key record to register.
* @param[in] aRequestId The ID associated with this request.
* @param[in] aCallback The callback function pointer to report the outcome (may be NULL if no callback needed).
*
*/
void otPlatDnssdRegisterKey(otInstance *aInstance,
const otPlatDnssdKey *aKey,
otPlatDnssdRequestId aRequestId,
otPlatDnssdRegisterCallback aCallback);
/**
* Unregisters a key record on the infrastructure network's DNS-SD module.
*
* The @p aKey and all its contained information (strings and arrays) are only valid during this call. The
* platform MUST save a copy of the information if it wants to retain the information after returning from this
* function.
*
* The fields in @p aKey follow these rules:
*
* - If the key is associated with a host, `mName` field specifies the host name and `mServiceType` will be NULL.
* - If the key is associated with a service, `mName` field specifies the service instance label and `mServiceType`
* field specifies the service type. In this case the DNS name for key record is `{mName}.{mServiceTye}`.
* - The `mInfraIfIndex` field, if non-zero, specifies the infrastructure network interface index to use for this
* request. If zero, the platform implementation can decided the interface.
* - The rest of the fields in @p aKey structure MUST be ignored in `otPlatDnssdUnregisterKey()` call and may
* be set to zero by the OpenThread stack.
*
* Regarding the invocation of the @p aCallback and the reuse of the @p aRequestId, this function follows the same
* rules as described in `otPlatDnssdRegisterService()`.
*
* The OpenThread stack may request the unregistration of a key that was not previously registered, and the platform
* implementation MUST handle this case. In such a case, the platform can use either `OT_ERROR_NOT_FOUND` to indicate
* that there was no such registration, or `OT_ERROR_NONE` when invoking the @p aCallback function. the OpenThread
* stack will handle either case correctly.
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aKey Information about the key to unregister.
* @param[in] aRequestId The ID associated with this request.
* @param[in] aCallback The callback function pointer to report the outcome (may be NULL if no callback needed).
*
*/
void otPlatDnssdUnregisterKey(otInstance *aInstance,
const otPlatDnssdKey *aKey,
otPlatDnssdRequestId aRequestId,
otPlatDnssdRegisterCallback aCallback);
/**
* @}
*
*/
#ifdef __cplusplus
} // extern "C"
#endif
#endif // OPENTHREAD_PLATFORM_DNSSD_H_