1 /*
2  *  Copyright (c) 2021, 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  * @brief
32  *  This file defines the DNS-SD server APIs.
33  */
34 
35 #ifndef OPENTHREAD_DNSSD_SERVER_H_
36 #define OPENTHREAD_DNSSD_SERVER_H_
37 
38 #include <stdint.h>
39 
40 #include <openthread/dns.h>
41 #include <openthread/error.h>
42 #include <openthread/ip6.h>
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47 
48 /**
49  * @addtogroup api-dnssd-server
50  *
51  * @brief
52  *   This module includes APIs for DNS-SD server.
53  *
54  * @{
55  *
56  */
57 
58 /**
59  * This function is called when a DNS-SD query subscribes one of:
60  *      1. a service name.
61  *      2. a service instance name.
62  *      3. a host name.
63  *
64  * The DNS-SD query implementation is responsible for identifying what @p aFullName is.
65  * If @p aFullName is a service name or service instance name, the DNS-SD query implementation should discover
66  * corresponding service instance information and notify the DNS-SD server using
67  * `otDnssdQueryHandleDiscoveredServiceInstance`.
68  * If @p aFullName is a host name, the DNS-SD query implementation should
69  * discover the host information and notify the DNS-SD server using `otDnssdQueryHandleDiscoveredHost`.
70  *
71  * @note There can be multiple subscription to the same name. DNS-SD query implementation should record the number of
72  * active subscriptions and stop notifying when there is no active subscription for @p aFullName.
73  *
74  * @param[in] aContext      A pointer to the application-specific context.
75  * @param[in] aFullName     The null-terminated full service name (e.g. "_ipps._tcp.default.service.arpa."),
76  *                          or full service instance name (e.g. "OpenThread._ipps._tcp.default.service.arpa."),
77  *                          or full host name (e.g. "ot-host.default.service.arpa.").
78  *
79  * @sa otDnssdQueryHandleDiscoveredServiceInstance
80  * @sa otDnssdQueryHandleDiscoveredHost
81  *
82  */
83 typedef void (*otDnssdQuerySubscribeCallback)(void *aContext, const char *aFullName);
84 
85 /**
86  * This function is called when a DNS-SD query unsubscribes one of:
87  *      1. a service name.
88  *      2. a service instance name.
89  *      3. a host name.
90  *
91  * The DNS-SD query implementation is responsible for identifying what @p aFullName is.
92  *
93  * @note There can be multiple subscription to the same name. DNS-SD query implementation should record the number of
94  * active subscriptions and stop notifying when there is no active subscription for @p aFullName.
95  *
96  * @param[in] aContext      A pointer to the application-specific context.
97  * @param[in] aFullName     The null-terminated full service name (e.g. "_ipps._tcp.default.service.arpa."), or
98  *                          full service instance name (e.g. "OpenThread._ipps._tcp.default.service.arpa.").
99  *
100  */
101 typedef void (*otDnssdQueryUnsubscribeCallback)(void *aContext, const char *aFullName);
102 
103 /**
104  * This opaque type represents a DNS-SD query.
105  *
106  */
107 typedef void otDnssdQuery;
108 
109 /**
110  * This structure represents information of a discovered service instance for a DNS-SD query.
111  *
112  */
113 typedef struct otDnssdServiceInstanceInfo
114 {
115     const char *        mFullName;   ///< Full instance name (e.g. "OpenThread._ipps._tcp.default.service.arpa.").
116     const char *        mHostName;   ///< Host name (e.g. "ot-host.default.service.arpa.").
117     uint8_t             mAddressNum; ///< Number of host IPv6 addresses.
118     const otIp6Address *mAddresses;  ///< Host IPv6 addresses.
119     uint16_t            mPort;       ///< Service port.
120     uint16_t            mPriority;   ///< Service priority.
121     uint16_t            mWeight;     ///< Service weight.
122     uint16_t            mTxtLength;  ///< Service TXT RDATA length.
123     const uint8_t *     mTxtData;    ///< Service TXT RDATA.
124     uint32_t            mTtl;        ///< Service TTL (in seconds).
125 } otDnssdServiceInstanceInfo;
126 
127 /**
128  * This structure represents information of a discovered host for a DNS-SD query.
129  *
130  */
131 typedef struct otDnssdHostInfo
132 {
133     uint8_t             mAddressNum; ///< Number of host IPv6 addresses.
134     const otIp6Address *mAddresses;  ///< Host IPv6 addresses.
135     uint32_t            mTtl;        ///< Service TTL (in seconds).
136 } otDnssdHostInfo;
137 
138 /**
139  * This enumeration specifies a DNS-SD query type.
140  *
141  */
142 typedef enum
143 {
144     OT_DNSSD_QUERY_TYPE_NONE         = 0, ///< Service type unspecified.
145     OT_DNSSD_QUERY_TYPE_BROWSE       = 1, ///< Service type browse service.
146     OT_DNSSD_QUERY_TYPE_RESOLVE      = 2, ///< Service type resolve service instance.
147     OT_DNSSD_QUERY_TYPE_RESOLVE_HOST = 3, ///< Service type resolve hostname.
148 } otDnssdQueryType;
149 
150 /**
151  * This function sets DNS-SD server query callbacks.
152  *
153  * The DNS-SD server calls @p aSubscribe to subscribe to a service or service instance to resolve a DNS-SD query and @p
154  * aUnsubscribe to unsubscribe when the query is resolved or timeout.
155  *
156  * @note @p aSubscribe and @p aUnsubscribe must be both set or unset.
157  *
158  * @param[in] aInstance     The OpenThread instance structure.
159  * @param[in] aSubscribe    A pointer to the callback function to subscribe a service or service instance.
160  * @param[in] aUnsubscribe  A pointer to the callback function to unsubscribe a service or service instance.
161  * @param[in] aContext      A pointer to the application-specific context.
162  *
163  */
164 void otDnssdQuerySetCallbacks(otInstance *                    aInstance,
165                               otDnssdQuerySubscribeCallback   aSubscribe,
166                               otDnssdQueryUnsubscribeCallback aUnsubscribe,
167                               void *                          aContext);
168 
169 /**
170  * This function notifies a discovered service instance.
171  *
172  * The external query resolver (e.g. Discovery Proxy) should call this function to notify OpenThread core of the
173  * subscribed services or service instances.
174  *
175  * @note @p aInstanceInfo must not contain unspecified or link-local or loop-back or multicast IP addresses.
176  *
177  * @param[in] aInstance         The OpenThread instance structure.
178  * @param[in] aServiceFullName  The null-terminated full service name.
179  * @param[in] aInstanceInfo     A pointer to the discovered service instance information.
180  *
181  */
182 void otDnssdQueryHandleDiscoveredServiceInstance(otInstance *                aInstance,
183                                                  const char *                aServiceFullName,
184                                                  otDnssdServiceInstanceInfo *aInstanceInfo);
185 /**
186  * This function notifies a discovered host.
187  *
188  * The external query resolver (e.g. Discovery Proxy) should call this function to notify OpenThread core of the
189  * subscribed hosts.
190  *
191  * @note @p aHostInfo must not contain unspecified or link-local or loop-back or multicast IP addresses.
192  *
193  * @param[in] aInstance         The OpenThread instance structure.
194  * @param[in] aHostFullName     The null-terminated full host name.
195  * @param[in] aHostInfo         A pointer to the discovered service instance information.
196  *
197  */
198 void otDnssdQueryHandleDiscoveredHost(otInstance *aInstance, const char *aHostFullName, otDnssdHostInfo *aHostInfo);
199 
200 /**
201  * This function aquires the next query in the DNS-SD server.
202  *
203  * @param[in] aInstance         The OpenThread instance structure.
204  * @param[in] aQuery            The query pointer. Pass NULL to get the first query.
205  *
206  * @returns  A pointer to the query or NULL if no more queries.
207  *
208  */
209 const otDnssdQuery *otDnssdGetNextQuery(otInstance *aInstance, const otDnssdQuery *aQuery);
210 
211 /**
212  * This function aquires the DNS-SD query type and name for a specific query.
213  *
214  * @param[in]   aQuery            The query pointer acquired from `otDnssdGetNextQuery`.
215  * @param[out]  aNameOutput       The name output buffer, which should be `OT_DNS_MAX_NAME_SIZE` bytes long.
216  *
217  * @returns The DNS-SD query type.
218  *
219  */
220 otDnssdQueryType otDnssdGetQueryTypeAndName(const otDnssdQuery *aQuery, char (*aNameOutput)[OT_DNS_MAX_NAME_SIZE]);
221 
222 /**
223  * @}
224  *
225  */
226 
227 #ifdef __cplusplus
228 } // extern "C"
229 #endif
230 
231 #endif // OPENTHREAD_DNSSD_SERVER_H_
232