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 OpenThread Network Data Publisher API.
33  */
34 
35 #ifndef OPENTHREAD_NETDATA_PUBLISHER_H_
36 #define OPENTHREAD_NETDATA_PUBLISHER_H_
37 
38 #include <openthread/netdata.h>
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 /**
45  * @addtogroup api-thread-general
46  *
47  * @{
48  *
49  * The Network Data Publisher provides mechanisms to limit the number of similar Service and/or Prefix (on-mesh prefix
50  * or external route) entries in the Thread Network Data by monitoring the Network Data and managing if or when to add
51  * or remove entries.
52  *
53  * All the functions in this module require `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE` to be enabled.
54  *
55  */
56 
57 /**
58  * Represents the events reported from the Publisher callbacks.
59  *
60  */
61 typedef enum otNetDataPublisherEvent
62 {
63     OT_NETDATA_PUBLISHER_EVENT_ENTRY_ADDED   = 0, ///< Published entry is added to the Thread Network Data.
64     OT_NETDATA_PUBLISHER_EVENT_ENTRY_REMOVED = 1, ///< Published entry is removed from the Thread Network Data.
65 } otNetDataPublisherEvent;
66 
67 /**
68  * Pointer type defines the callback used to notify when a "DNS/SRP Service" entry is added to or removed
69  * from the Thread Network Data.
70  *
71  * On remove the callback is invoked independent of whether the entry is removed by `Publisher` (e.g., when there are
72  * too many similar entries already present in the Network Data) or through an explicit call to unpublish the entry
73  * (i.e., a call to `otNetDataUnpublishDnsSrpService()`).
74  *
75  * @param[in] aEvent     Indicates the event (whether the entry was added or removed).
76  * @param[in] aContext   A pointer to application-specific context.
77  *
78  */
79 typedef void (*otNetDataDnsSrpServicePublisherCallback)(otNetDataPublisherEvent aEvent, void *aContext);
80 
81 /**
82  * Pointer type defines the callback used to notify when a prefix (on-mesh or external route) entry is
83  * added to or removed from the Thread Network Data.
84  *
85  * On remove the callback is invoked independent of whether the entry is removed by `Publisher` (e.g., when there are
86  * too many similar entries already present in the Network Data) or through an explicit call to unpublish the entry.
87  *
88  * @param[in] aEvent     Indicates the event (whether the entry was added or removed).
89  * @param[in] aPrefix    A pointer to the prefix entry.
90  * @param[in] aContext   A pointer to application-specific context.
91  *
92  */
93 typedef void (*otNetDataPrefixPublisherCallback)(otNetDataPublisherEvent aEvent,
94                                                  const otIp6Prefix      *aPrefix,
95                                                  void                   *aContext);
96 
97 /**
98  * Requests "DNS/SRP Service Anycast Address" to be published in the Thread Network Data.
99  *
100  * Requires the feature `OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE` to be enabled.
101  *
102  * A call to this function will remove and replace any previous "DNS/SRP Service" entry that was being published (from
103  * earlier call to any of `otNetDataPublishDnsSrpService{Type}()` functions).
104  *
105  * @param[in] aInstance        A pointer to an OpenThread instance.
106  * @param[in] aSequenceNUmber  The sequence number of DNS/SRP Anycast Service.
107  *
108  */
109 void otNetDataPublishDnsSrpServiceAnycast(otInstance *aInstance, uint8_t aSequenceNUmber);
110 
111 /**
112  * Requests "DNS/SRP Service Unicast Address" to be published in the Thread Network Data.
113  *
114  * Requires the feature `OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE` to be enabled.
115  *
116  * A call to this function will remove and replace any previous "DNS/SRP Service" entry that was being published (from
117  * earlier call to any of `otNetDataPublishDnsSrpService{Type}()` functions).
118  *
119  * Publishes the "DNS/SRP Service Unicast Address" by including the address and port info in the Service
120  * TLV data.
121  *
122  * @param[in] aInstance  A pointer to an OpenThread instance.
123  * @param[in] aAddress   The DNS/SRP server address to publish (MUST NOT be NULL).
124  * @param[in] aPort      The SRP server port number to publish.
125  *
126  */
127 void otNetDataPublishDnsSrpServiceUnicast(otInstance *aInstance, const otIp6Address *aAddress, uint16_t aPort);
128 
129 /**
130  * Requests "DNS/SRP Service Unicast Address" to be published in the Thread Network Data.
131  *
132  * Requires the feature `OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE` to be enabled.
133  *
134  * A call to this function will remove and replace any previous "DNS/SRP Service" entry that was being published (from
135  * earlier call to any of `otNetDataPublishDnsSrpService{Type}()` functions).
136  *
137  * Unlike `otNetDataPublishDnsSrpServiceUnicast()` which requires the published address to be given and includes the
138  * info in the Service TLV data, this function uses the device's mesh-local EID and includes the info in the Server TLV
139  * data.
140  *
141  * @param[in] aInstance  A pointer to an OpenThread instance.
142  * @param[in] aPort      The SRP server port number to publish.
143  *
144  */
145 void otNetDataPublishDnsSrpServiceUnicastMeshLocalEid(otInstance *aInstance, uint16_t aPort);
146 
147 /**
148  * Indicates whether or not currently the "DNS/SRP Service" entry is added to the Thread Network Data.
149  *
150  * Requires the feature `OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE` to be enabled.
151  *
152  * @param[in] aInstance  A pointer to an OpenThread instance.
153  *
154  * @retval TRUE    The published DNS/SRP Service entry is added to the Thread Network Data.
155  * @retval FALSE   The entry is not added to Thread Network Data or there is no entry to publish.
156  *
157  */
158 bool otNetDataIsDnsSrpServiceAdded(otInstance *aInstance);
159 
160 /**
161  * Sets a callback for notifying when a published "DNS/SRP Service" is actually added to or removed from
162  * the Thread Network Data.
163  *
164  * A subsequent call to this function replaces any previously set callback function.
165  *
166  * Requires the feature `OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE` to be enabled.
167  *
168  * @param[in] aInstance        A pointer to an OpenThread instance.
169  * @param[in] aCallback        The callback function pointer (can be NULL if not needed).
170  * @param[in] aContext         A pointer to application-specific context (used when @p aCallback is invoked).
171  *
172  */
173 void otNetDataSetDnsSrpServicePublisherCallback(otInstance                             *aInstance,
174                                                 otNetDataDnsSrpServicePublisherCallback aCallback,
175                                                 void                                   *aContext);
176 
177 /**
178  * Unpublishes any previously added DNS/SRP (Anycast or Unicast) Service entry from the Thread Network
179  * Data.
180  *
181  * `OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE` must be enabled.
182  *
183  * @param[in] aInstance  A pointer to an OpenThread instance.
184  *
185  */
186 void otNetDataUnpublishDnsSrpService(otInstance *aInstance);
187 
188 /**
189  * Requests an on-mesh prefix to be published in the Thread Network Data.
190  *
191  * Requires the feature `OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE` to be enabled.
192  *
193  * Only stable entries can be published (i.e.,`aConfig.mStable` MUST be TRUE).
194  *
195  * A subsequent call to this method will replace a previous request for the same prefix. In particular, if the new call
196  * only changes the flags (e.g., preference level) and the prefix is already added in the Network Data, the change to
197  * flags is immediately reflected in the Network Data. This ensures that existing entries in the Network Data are not
198  * abruptly removed. Note that a change in the preference level can potentially later cause the entry to be removed
199  * from the Network Data after determining there are other nodes that are publishing the same prefix with the same or
200  * higher preference.
201  *
202  * @param[in] aInstance           A pointer to an OpenThread instance.
203  * @param[in] aConfig             The on-mesh prefix config to publish (MUST NOT be NULL).
204  *
205  * @retval OT_ERROR_NONE          The on-mesh prefix is published successfully.
206  * @retval OT_ERROR_INVALID_ARGS  The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
207  * @retval OT_ERROR_NO_BUFS       Could not allocate an entry for the new request. Publisher supports a limited number
208  *                                of entries (shared between on-mesh prefix and external route) determined by config
209  *                                `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
210  *
211  *
212  */
213 otError otNetDataPublishOnMeshPrefix(otInstance *aInstance, const otBorderRouterConfig *aConfig);
214 
215 /**
216  * Requests an external route prefix to be published in the Thread Network Data.
217  *
218  * Requires the feature `OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE` to be enabled.
219  *
220  * Only stable entries can be published (i.e.,`aConfig.mStable` MUST be TRUE).
221  *
222  * A subsequent call to this method will replace a previous request for the same prefix. In particular, if the new call
223  * only changes the flags (e.g., preference level) and the prefix is already added in the Network Data, the change to
224  * flags is immediately reflected in the Network Data. This ensures that existing entries in the Network Data are not
225  * abruptly removed. Note that a change in the preference level can potentially later cause the entry to be removed
226  * from the Network Data after determining there are other nodes that are publishing the same prefix with the same or
227  * higher preference.
228  *
229  * @param[in] aInstance           A pointer to an OpenThread instance.
230  * @param[in] aConfig             The external route config to publish (MUST NOT be NULL).
231  *
232  * @retval OT_ERROR_NONE          The external route is published successfully.
233  * @retval OT_ERROR_INVALID_ARGS  The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
234  * @retval OT_ERROR_NO_BUFS       Could not allocate an entry for the new request. Publisher supports a limited number
235  *                                of entries (shared between on-mesh prefix and external route) determined by config
236  *                                `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
237  */
238 otError otNetDataPublishExternalRoute(otInstance *aInstance, const otExternalRouteConfig *aConfig);
239 
240 /**
241  * Replaces a previously published external route in the Thread Network Data.
242  *
243  * Requires the feature `OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE` to be enabled.
244  *
245  * If there is no previously published external route matching @p aPrefix, this function behaves similarly to
246  * `otNetDataPublishExternalRoute()`, i.e., it will start the process of publishing @a aConfig as an external route in
247  * the Thread Network Data.
248  *
249  * If there is a previously published route entry matching @p aPrefix, it will be replaced with the new prefix from
250  * @p aConfig.
251  *
252  * - If the @p aPrefix was already added in the Network Data, the change to the new prefix in @p aConfig is immediately
253  *   reflected in the Network Data. This ensures that route entries in the Network Data are not abruptly removed and
254  *   the transition from aPrefix to the new prefix is smooth.
255  *
256  * - If the old published @p aPrefix was not added in the Network Data, it will be replaced with the new @p aConfig
257  *   prefix but it will not be immediately added. Instead, it will start the process of publishing it in the Network
258  *   Data (monitoring the Network Data to determine when/if to add the prefix, depending on the number of similar
259  *   prefixes present in the Network Data).
260  *
261  * @param[in] aPrefix         The previously published external route prefix to replace.
262  * @param[in] aConfig         The external route config to publish.
263  * @param[in] aRequester      The requester (`kFromUser` or `kFromRoutingManager` module).
264  *
265  * @retval OT_ERROR_NONE          The external route is published successfully.
266  * @retval OT_ERROR_INVALID_ARGS  The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
267  * @retval OT_ERROR_NO_BUFS       Could not allocate an entry for the new request. Publisher supports a limited number
268  *                                of entries (shared between on-mesh prefix and external route) determined by config
269  *                                `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
270  *
271  */
272 otError otNetDataReplacePublishedExternalRoute(otInstance                  *aInstance,
273                                                const otIp6Prefix           *aPrefix,
274                                                const otExternalRouteConfig *aConfig);
275 
276 /**
277  * Indicates whether or not currently a published prefix entry (on-mesh or external route) is added to
278  * the Thread Network Data.
279  *
280  * Requires the feature `OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE` to be enabled.
281  *
282  * @param[in] aInstance  A pointer to an OpenThread instance.
283  * @param[in] aPrefix    A pointer to the prefix (MUST NOT be NULL).
284  *
285  * @retval TRUE    The published prefix entry is added to the Thread Network Data.
286  * @retval FALSE   The entry is not added to Thread Network Data or there is no entry to publish.
287  *
288  */
289 bool otNetDataIsPrefixAdded(otInstance *aInstance, const otIp6Prefix *aPrefix);
290 
291 /**
292  * Sets a callback for notifying when a published prefix entry is actually added to or removed from
293  * the Thread Network Data.
294  *
295  * A subsequent call to this function replaces any previously set callback function.
296  *
297  * Requires the feature `OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE` to be enabled.
298  *
299  * @param[in] aInstance        A pointer to an OpenThread instance.
300  * @param[in] aCallback        The callback function pointer (can be NULL if not needed).
301  * @param[in] aContext         A pointer to application-specific context (used when @p aCallback is invoked).
302  *
303  */
304 void otNetDataSetPrefixPublisherCallback(otInstance                      *aInstance,
305                                          otNetDataPrefixPublisherCallback aCallback,
306                                          void                            *aContext);
307 
308 /**
309  * Unpublishes a previously published On-Mesh or External Route Prefix.
310  *
311  * `OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE` must be enabled.
312  *
313  * @param[in] aInstance          A pointer to an OpenThread instance.
314  * @param[in] aPrefix            The prefix to unpublish (MUST NOT be NULL).
315  *
316  * @retval OT_ERROR_NONE         The prefix was unpublished successfully.
317  * @retval OT_ERROR_NOT_FOUND    Could not find the prefix in the published list.
318  *
319  */
320 otError otNetDataUnpublishPrefix(otInstance *aInstance, const otIp6Prefix *aPrefix);
321 
322 /**
323  * @}
324  *
325  */
326 
327 #ifdef __cplusplus
328 } // extern "C"
329 #endif
330 
331 #endif // OPENTHREAD_NETDATA_PUBLISHER_H_
332