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