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