1 /*
2 * Copyright (c) 2016-21, 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 Network Data types and constants.
32 */
33
34 #ifndef NETWORK_DATA_TYPES_HPP_
35 #define NETWORK_DATA_TYPES_HPP_
36
37 #include "openthread-core-config.h"
38
39 #include <openthread/netdata.h>
40
41 #include "common/array.hpp"
42 #include "common/as_core_type.hpp"
43 #include "common/clearable.hpp"
44 #include "common/data.hpp"
45 #include "common/debug.hpp"
46 #include "common/equatable.hpp"
47 #include "common/preference.hpp"
48 #include "net/ip6_address.hpp"
49
50 namespace ot {
51
52 class Instance;
53
54 namespace NetworkData {
55
56 /**
57 * @addtogroup core-netdata-core
58 *
59 */
60
61 // Forward declarations
62 class NetworkData;
63 class Local;
64 class Publisher;
65 class PrefixTlv;
66 class BorderRouterTlv;
67 class BorderRouterEntry;
68 class HasRouteTlv;
69 class HasRouteEntry;
70 class ServiceTlv;
71 class ServerTlv;
72 class ContextTlv;
73
74 /**
75 * Represents the Network Data type.
76 *
77 */
78 enum Type : uint8_t
79 {
80 kFullSet, ///< Full Network Data set.
81 kStableSubset, ///< Stable Network Data subset.
82 };
83
84 /**
85 * Type represents the route preference values as a signed integer (per RFC-4191).
86 *
87 */
88 enum RoutePreference : int8_t
89 {
90 kRoutePreferenceLow = OT_ROUTE_PREFERENCE_LOW, ///< Low route preference.
91 kRoutePreferenceMedium = OT_ROUTE_PREFERENCE_MED, ///< Medium route preference.
92 kRoutePreferenceHigh = OT_ROUTE_PREFERENCE_HIGH, ///< High route preference.
93 };
94
95 static_assert(kRoutePreferenceHigh == Preference::kHigh, "kRoutePreferenceHigh is not valid");
96 static_assert(kRoutePreferenceMedium == Preference::kMedium, "kRoutePreferenceMedium is not valid");
97 static_assert(kRoutePreferenceLow == Preference::kLow, "kRoutePreferenceLow is not valid");
98
99 /**
100 * Represents the border router RLOC role filter used when searching for border routers in the Network
101 * Data.
102 *
103 */
104 enum RoleFilter : uint8_t
105 {
106 kAnyRole, ///< Include devices in any role.
107 kRouterRoleOnly, ///< Include devices that act as Thread router.
108 kChildRoleOnly, ///< Include devices that act as Thread child (end-device).
109 };
110
111 /**
112 * Represents the entry filter used when searching for RLOC16 of border routers or servers in the Network Data.
113 *
114 * Regarding `kBrProvidingExternalIpConn`, a border router is considered to provide external IP connectivity if at
115 * least one of the below conditions hold:
116 *
117 * - It has added at least one external route entry.
118 * - It has added at least one prefix entry with default-route and on-mesh flags set.
119 * - It has added at least one domain prefix (domain and on-mesh flags set).
120 *
121 */
122 enum BorderRouterFilter : uint8_t
123 {
124 kAnyBrOrServer, ///< Include any border router or server entry.
125 kBrProvidingExternalIpConn, ///< Include border routers providing external IP connectivity.
126 };
127
128 /**
129 * Maximum length of `Rlocs` array containing RLOC16 of all border routers and servers in the Network Data.
130 *
131 * This limit is derived from the maximum Network Data size (254 bytes) and the minimum size of an external route entry
132 * (3 bytes including the RLOC16 and flags) as `ceil(254/3) = 85`.
133 *
134 */
135 static constexpr uint8_t kMaxRlocs = 85;
136
137 /**
138 * An array containing RLOC16 of all border routers and server in the Network Data.
139 *
140 */
141 typedef Array<uint16_t, kMaxRlocs> Rlocs;
142
143 /**
144 * Indicates whether a given `int8_t` preference value is a valid route preference (i.e., one of the
145 * values from `RoutePreference` enumeration).
146 *
147 * @param[in] aPref The signed route preference value.
148 *
149 * @retval TRUE if @p aPref is valid.
150 * @retval FALSE if @p aPref is not valid
151 *
152 */
IsRoutePreferenceValid(int8_t aPref)153 inline bool IsRoutePreferenceValid(int8_t aPref) { return Preference::IsValid(aPref); }
154
155 /**
156 * Coverts a route preference to a 2-bit unsigned value.
157 *
158 * The @p aPref MUST be valid (value from `RoutePreference` enumeration), or the behavior is undefined.
159 *
160 * @param[in] aPref The route preference to convert.
161 *
162 * @returns The 2-bit unsigned value representing @p aPref.
163 *
164 */
RoutePreferenceToValue(int8_t aPref)165 inline uint8_t RoutePreferenceToValue(int8_t aPref) { return Preference::To2BitUint(aPref); }
166
167 /**
168 * Coverts a 2-bit unsigned value to a route preference.
169 *
170 * @param[in] aValue The 2-bit unsigned value to convert from. Note that only the first two bits of @p aValue
171 * are used and the rest of bits are ignored.
172 *
173 * @returns The route preference corresponding to @p aValue.
174 *
175 */
RoutePreferenceFromValue(uint8_t aValue)176 inline RoutePreference RoutePreferenceFromValue(uint8_t aValue)
177 {
178 return static_cast<RoutePreference>(Preference::From2BitUint(aValue));
179 }
180
181 /**
182 * Converts a router preference to a human-readable string.
183 *
184 * @param[in] aPreference The preference to convert
185 *
186 * @returns The string representation of @p aPreference.
187 *
188 */
RoutePreferenceToString(RoutePreference aPreference)189 inline const char *RoutePreferenceToString(RoutePreference aPreference) { return Preference::ToString(aPreference); }
190
191 /**
192 * Represents an On-mesh Prefix (Border Router) configuration.
193 *
194 */
195 class OnMeshPrefixConfig : public otBorderRouterConfig,
196 public Clearable<OnMeshPrefixConfig>,
197 public Equatable<OnMeshPrefixConfig>
198 {
199 friend class NetworkData;
200 friend class Leader;
201 friend class Local;
202 friend class Publisher;
203
204 public:
205 /**
206 * Gets the prefix.
207 *
208 * @return The prefix.
209 *
210 */
GetPrefix(void) const211 const Ip6::Prefix &GetPrefix(void) const { return AsCoreType(&mPrefix); }
212
213 /**
214 * Gets the prefix.
215 *
216 * @return The prefix.
217 *
218 */
GetPrefix(void)219 Ip6::Prefix &GetPrefix(void) { return AsCoreType(&mPrefix); }
220
221 /**
222 * Gets the preference.
223 *
224 * @return The preference.
225 *
226 */
GetPreference(void) const227 RoutePreference GetPreference(void) const { return RoutePreferenceFromValue(RoutePreferenceToValue(mPreference)); }
228
229 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
230 /**
231 * Indicates whether or not the prefix configuration is valid.
232 *
233 * @param[in] aInstance A reference to the OpenThread instance.
234 *
235 * @retval TRUE The config is a valid on-mesh prefix.
236 * @retval FALSE The config is not a valid on-mesh prefix.
237 *
238 */
239 bool IsValid(Instance &aInstance) const;
240 #endif
241
242 private:
243 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
244 uint16_t ConvertToTlvFlags(void) const;
245 #endif
246 void SetFrom(const PrefixTlv &aPrefixTlv,
247 const BorderRouterTlv &aBorderRouterTlv,
248 const BorderRouterEntry &aBorderRouterEntry);
249 void SetFromTlvFlags(uint16_t aFlags);
250 };
251
252 /**
253 * Represents an External Route configuration.
254 *
255 */
256 class ExternalRouteConfig : public otExternalRouteConfig,
257 public Clearable<ExternalRouteConfig>,
258 public Equatable<ExternalRouteConfig>
259 {
260 friend class NetworkData;
261 friend class Local;
262 friend class Publisher;
263
264 public:
265 /**
266 * Gets the prefix.
267 *
268 * @return The prefix.
269 *
270 */
GetPrefix(void) const271 const Ip6::Prefix &GetPrefix(void) const { return AsCoreType(&mPrefix); }
272
273 /**
274 * Gets the prefix.
275 *
276 * @return The prefix.
277 *
278 */
GetPrefix(void)279 Ip6::Prefix &GetPrefix(void) { return AsCoreType(&mPrefix); }
280
281 /**
282 * Sets the prefix.
283 *
284 * @param[in] aPrefix The prefix to set to.
285 *
286 */
SetPrefix(const Ip6::Prefix & aPrefix)287 void SetPrefix(const Ip6::Prefix &aPrefix) { mPrefix = aPrefix; }
288
289 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
290 /**
291 * Indicates whether or not the external route configuration is valid.
292 *
293 * @param[in] aInstance A reference to the OpenThread instance.
294 *
295 * @retval TRUE The config is a valid external route.
296 * @retval FALSE The config is not a valid extern route.
297 *
298 */
299 bool IsValid(Instance &aInstance) const;
300 #endif
301
302 private:
303 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
304 uint8_t ConvertToTlvFlags(void) const;
305 #endif
306 void SetFrom(Instance &aInstance,
307 const PrefixTlv &aPrefixTlv,
308 const HasRouteTlv &aHasRouteTlv,
309 const HasRouteEntry &aHasRouteEntry);
310 void SetFromTlvFlags(uint8_t aFlags);
311 };
312
313 /**
314 * Represents 6LoWPAN Context ID information associated with a prefix in Network Data.
315 *
316 */
317 class LowpanContextInfo : public otLowpanContextInfo, public Clearable<LowpanContextInfo>
318 {
319 friend class NetworkData;
320
321 public:
322 /**
323 * Gets the prefix.
324 *
325 * @return The prefix.
326 *
327 */
GetPrefix(void) const328 const Ip6::Prefix &GetPrefix(void) const { return AsCoreType(&mPrefix); }
329
330 private:
GetPrefix(void)331 Ip6::Prefix &GetPrefix(void) { return AsCoreType(&mPrefix); }
332 void SetFrom(const PrefixTlv &aPrefixTlv, const ContextTlv &aContextTlv);
333 };
334
335 /**
336 * Represents a Service Data.
337 *
338 */
339 class ServiceData : public Data<kWithUint8Length>
340 {
341 };
342
343 /**
344 * Represents a Server Data.
345 *
346 */
347 class ServerData : public Data<kWithUint8Length>
348 {
349 };
350
351 /**
352 * Represents a Service configuration.
353 *
354 */
355 class ServiceConfig : public otServiceConfig, public Clearable<ServiceConfig>, public Unequatable<ServiceConfig>
356 {
357 friend class NetworkData;
358
359 public:
360 /**
361 * Represents a Server configuration.
362 *
363 */
364 class ServerConfig : public otServerConfig, public Unequatable<ServerConfig>
365 {
366 friend class ServiceConfig;
367
368 public:
369 /**
370 * Gets the Server Data.
371 *
372 * @param[out] aServerData A reference to a`ServerData` to return the data.
373 *
374 */
GetServerData(ServerData & aServerData) const375 void GetServerData(ServerData &aServerData) const { aServerData.Init(mServerData, mServerDataLength); }
376
377 /**
378 * Overloads operator `==` to evaluate whether or not two `ServerConfig` instances are equal.
379 *
380 * @param[in] aOther The other `ServerConfig` instance to compare with.
381 *
382 * @retval TRUE If the two `ServerConfig` instances are equal.
383 * @retval FALSE If the two `ServerConfig` instances are not equal.
384 *
385 */
386 bool operator==(const ServerConfig &aOther) const;
387
388 private:
389 void SetFrom(const ServerTlv &aServerTlv);
390 };
391
392 /**
393 * Gets the Service Data.
394 *
395 * @param[out] aServiceData A reference to a `ServiceData` to return the data.
396 *
397 */
GetServiceData(ServiceData & aServiceData) const398 void GetServiceData(ServiceData &aServiceData) const { aServiceData.Init(mServiceData, mServiceDataLength); }
399
400 /**
401 * Gets the Server configuration.
402 *
403 * @returns The Server configuration.
404 *
405 */
GetServerConfig(void) const406 const ServerConfig &GetServerConfig(void) const { return static_cast<const ServerConfig &>(mServerConfig); }
407
408 /**
409 * Gets the Server configuration.
410 *
411 * @returns The Server configuration.
412 *
413 */
GetServerConfig(void)414 ServerConfig &GetServerConfig(void) { return static_cast<ServerConfig &>(mServerConfig); }
415
416 /**
417 * Overloads operator `==` to evaluate whether or not two `ServiceConfig` instances are equal.
418 *
419 * @param[in] aOther The other `ServiceConfig` instance to compare with.
420 *
421 * @retval TRUE If the two `ServiceConfig` instances are equal.
422 * @retval FALSE If the two `ServiceConfig` instances are not equal.
423 *
424 */
425 bool operator==(const ServiceConfig &aOther) const;
426
427 private:
428 void SetFrom(const ServiceTlv &aServiceTlv, const ServerTlv &aServerTlv);
429 };
430
431 } // namespace NetworkData
432
433 DefineCoreType(otBorderRouterConfig, NetworkData::OnMeshPrefixConfig);
434 DefineCoreType(otExternalRouteConfig, NetworkData::ExternalRouteConfig);
435 DefineCoreType(otLowpanContextInfo, NetworkData::LowpanContextInfo);
436 DefineCoreType(otServiceConfig, NetworkData::ServiceConfig);
437 DefineCoreType(otServerConfig, NetworkData::ServiceConfig::ServerConfig);
438
439 /**
440 * @}
441 */
442
443 } // namespace ot
444
445 #endif // NETWORK_DATA_TYPES_HPP_
446