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/as_core_type.hpp"
42 #include "common/clearable.hpp"
43 #include "common/data.hpp"
44 #include "common/debug.hpp"
45 #include "common/equatable.hpp"
46 #include "net/ip6_address.hpp"
47
48 namespace ot {
49
50 class Instance;
51
52 namespace NetworkData {
53
54 /**
55 * @addtogroup core-netdata-core
56 *
57 */
58
59 // Forward declarations
60 class NetworkData;
61 class Local;
62 class Publisher;
63 class PrefixTlv;
64 class BorderRouterTlv;
65 class BorderRouterEntry;
66 class HasRouteTlv;
67 class HasRouteEntry;
68 class ServiceTlv;
69 class ServerTlv;
70
71 /**
72 * This enumeration represents the Network Data type.
73 *
74 */
75 enum Type : uint8_t
76 {
77 kFullSet, ///< Full Network Data set.
78 kStableSubset, ///< Stable Network Data subset.
79 };
80
81 /**
82 * This enumeration type represents the route preference values as a signed integer (per RFC-4191).
83 *
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 /**
93 * This enumeration represents the border router RLOC role filter used when searching for border routers in the Network
94 * Data.
95 *
96 */
97 enum RoleFilter : uint8_t
98 {
99 kAnyRole, ///< Include devices in any role.
100 kRouterRoleOnly, ///< Include devices that act as Thread router.
101 kChildRoleOnly, ///< Include devices that act as Thread child (end-device).
102 };
103
104 /**
105 * This function indicates whether a given `int8_t` preference value is a valid route preference (i.e., one of the
106 * values from `RoutePreference` enumeration).
107 *
108 * @param[in] aPref The signed route preference value.
109 *
110 * @retval TRUE if @p aPref is valid.
111 * @retval FALSE if @p aPref is not valid
112 *
113 */
IsRoutePreferenceValid(int8_t aPref)114 inline bool IsRoutePreferenceValid(int8_t aPref)
115 {
116 return (aPref == kRoutePreferenceLow) || (aPref == kRoutePreferenceMedium) || (aPref == kRoutePreferenceHigh);
117 }
118
119 /**
120 * This function coverts a route preference to a 2-bit unsigned value.
121 *
122 * The @p aPref MUST be valid (value from `RoutePreference` enumeration), or the behavior is undefined.
123 *
124 * @param[in] aPref The route preference to convert.
125 *
126 * @returns The 2-bit unsigned value representing @p aPref.
127 *
128 */
RoutePreferenceToValue(int8_t aPref)129 inline uint8_t RoutePreferenceToValue(int8_t aPref)
130 {
131 constexpr uint8_t kHigh = 1; // 01
132 constexpr uint8_t kMedium = 0; // 00
133 constexpr uint8_t kLow = 3; // 11
134
135 OT_ASSERT(IsRoutePreferenceValid(aPref));
136
137 return (aPref == 0) ? kMedium : ((aPref > 0) ? kHigh : kLow);
138 }
139
140 /**
141 * This function coverts a 2-bit unsigned value to a route preference.
142 *
143 * @param[in] aValue The 2-bit unsigned value to convert from. Note that only the first two bits of @p aValue
144 * are used and the rest of bits are ignored.
145 *
146 * @returns The route preference corresponding to @p aValue.
147 *
148 */
RoutePreferenceFromValue(uint8_t aValue)149 inline RoutePreference RoutePreferenceFromValue(uint8_t aValue)
150 {
151 constexpr uint8_t kMask = 3; // First two bits.
152
153 static const RoutePreference kRoutePreferences[] = {
154 /* 0 (00) -> */ kRoutePreferenceMedium,
155 /* 1 (01) -> */ kRoutePreferenceHigh,
156 /* 2 (10) -> */ kRoutePreferenceMedium, // Per RFC-4191, the reserved value (10) MUST be treated as (00)
157 /* 3 (11) -> */ kRoutePreferenceLow,
158 };
159
160 return kRoutePreferences[aValue & kMask];
161 }
162
163 /**
164 * This class represents an On-mesh Prefix (Border Router) configuration.
165 *
166 */
167 class OnMeshPrefixConfig : public otBorderRouterConfig,
168 public Clearable<OnMeshPrefixConfig>,
169 public Equatable<OnMeshPrefixConfig>
170 {
171 friend class NetworkData;
172 friend class Leader;
173 friend class Local;
174 friend class Publisher;
175
176 public:
177 /**
178 * This method gets the prefix.
179 *
180 * @return The prefix.
181 *
182 */
GetPrefix(void) const183 const Ip6::Prefix &GetPrefix(void) const { return AsCoreType(&mPrefix); }
184
185 /**
186 * This method gets the prefix.
187 *
188 * @return The prefix.
189 *
190 */
GetPrefix(void)191 Ip6::Prefix &GetPrefix(void) { return AsCoreType(&mPrefix); }
192
193 /**
194 * This method gets the preference.
195 *
196 * @return The preference.
197 *
198 */
GetPreference(void) const199 RoutePreference GetPreference(void) const { return RoutePreferenceFromValue(RoutePreferenceToValue(mPreference)); }
200
201 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
202 /**
203 * This method indicates whether or not the prefix configuration is valid.
204 *
205 * @param[in] aInstance A reference to the OpenThread instance.
206 *
207 * @retval TRUE The config is a valid on-mesh prefix.
208 * @retval FALSE The config is not a valid on-mesh prefix.
209 *
210 */
211 bool IsValid(Instance &aInstance) const;
212 #endif
213
214 private:
215 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
216 uint16_t ConvertToTlvFlags(void) const;
217 #endif
218 void SetFrom(const PrefixTlv & aPrefixTlv,
219 const BorderRouterTlv & aBorderRouterTlv,
220 const BorderRouterEntry &aBorderRouterEntry);
221 void SetFromTlvFlags(uint16_t aFlags);
222 };
223
224 /**
225 * This class represents an External Route configuration.
226 *
227 */
228 class ExternalRouteConfig : public otExternalRouteConfig,
229 public Clearable<ExternalRouteConfig>,
230 public Equatable<ExternalRouteConfig>
231 {
232 friend class NetworkData;
233 friend class Local;
234 friend class Publisher;
235
236 public:
237 /**
238 * This method gets the prefix.
239 *
240 * @return The prefix.
241 *
242 */
GetPrefix(void) const243 const Ip6::Prefix &GetPrefix(void) const { return AsCoreType(&mPrefix); }
244
245 /**
246 * This method gets the prefix.
247 *
248 * @return The prefix.
249 *
250 */
GetPrefix(void)251 Ip6::Prefix &GetPrefix(void) { return AsCoreType(&mPrefix); }
252
253 /**
254 * This method sets the prefix.
255 *
256 * @param[in] aPrefix The prefix to set to.
257 *
258 */
SetPrefix(const Ip6::Prefix & aPrefix)259 void SetPrefix(const Ip6::Prefix &aPrefix) { mPrefix = aPrefix; }
260
261 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
262 /**
263 * This method indicates whether or not the external route configuration is valid.
264 *
265 * @param[in] aInstance A reference to the OpenThread instance.
266 *
267 * @retval TRUE The config is a valid external route.
268 * @retval FALSE The config is not a valid extern route.
269 *
270 */
271 bool IsValid(Instance &aInstance) const;
272 #endif
273
274 private:
275 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
276 uint8_t ConvertToTlvFlags(void) const;
277 #endif
278 void SetFrom(Instance & aInstance,
279 const PrefixTlv & aPrefixTlv,
280 const HasRouteTlv & aHasRouteTlv,
281 const HasRouteEntry &aHasRouteEntry);
282 void SetFromTlvFlags(uint8_t aFlags);
283 };
284
285 /**
286 * This class represents a Service Data.
287 *
288 */
289 class ServiceData : public Data<kWithUint8Length>
290 {
291 };
292
293 /**
294 * This class represents a Server Data.
295 *
296 */
297 class ServerData : public Data<kWithUint8Length>
298 {
299 };
300
301 /**
302 * This type represents a Service configuration.
303 *
304 */
305 class ServiceConfig : public otServiceConfig, public Clearable<ServiceConfig>, public Unequatable<ServiceConfig>
306 {
307 friend class NetworkData;
308
309 public:
310 /**
311 * This class represents a Server configuration.
312 *
313 */
314 class ServerConfig : public otServerConfig, public Unequatable<ServerConfig>
315 {
316 friend class ServiceConfig;
317
318 public:
319 /**
320 * This method gets the Server Data.
321 *
322 * @param[out] aServerData A reference to a`ServerData` to return the data.
323 *
324 */
GetServerData(ServerData & aServerData) const325 void GetServerData(ServerData &aServerData) const { aServerData.Init(mServerData, mServerDataLength); }
326
327 /**
328 * This method overloads operator `==` to evaluate whether or not two `ServerConfig` instances are equal.
329 *
330 * @param[in] aOther The other `ServerConfig` instance to compare with.
331 *
332 * @retval TRUE If the two `ServerConfig` instances are equal.
333 * @retval FALSE If the two `ServerConfig` instances are not equal.
334 *
335 */
336 bool operator==(const ServerConfig &aOther) const;
337
338 private:
339 void SetFrom(const ServerTlv &aServerTlv);
340 };
341
342 /**
343 * This method gets the Service Data.
344 *
345 * @param[out] aServiceData A reference to a `ServiceData` to return the data.
346 *
347 */
GetServiceData(ServiceData & aServiceData) const348 void GetServiceData(ServiceData &aServiceData) const { aServiceData.Init(mServiceData, mServiceDataLength); }
349
350 /**
351 * This method gets the Server configuration.
352 *
353 * @returns The Server configuration.
354 *
355 */
GetServerConfig(void) const356 const ServerConfig &GetServerConfig(void) const { return static_cast<const ServerConfig &>(mServerConfig); }
357
358 /**
359 * This method gets the Server configuration.
360 *
361 * @returns The Server configuration.
362 *
363 */
GetServerConfig(void)364 ServerConfig &GetServerConfig(void) { return static_cast<ServerConfig &>(mServerConfig); }
365
366 /**
367 * This method overloads operator `==` to evaluate whether or not two `ServiceConfig` instances are equal.
368 *
369 * @param[in] aOther The other `ServiceConfig` instance to compare with.
370 *
371 * @retval TRUE If the two `ServiceConfig` instances are equal.
372 * @retval FALSE If the two `ServiceConfig` instances are not equal.
373 *
374 */
375 bool operator==(const ServiceConfig &aOther) const;
376
377 private:
378 void SetFrom(const ServiceTlv &aServiceTlv, const ServerTlv &aServerTlv);
379 };
380
381 } // namespace NetworkData
382
383 DefineCoreType(otBorderRouterConfig, NetworkData::OnMeshPrefixConfig);
384 DefineCoreType(otExternalRouteConfig, NetworkData::ExternalRouteConfig);
385 DefineCoreType(otServiceConfig, NetworkData::ServiceConfig);
386 DefineCoreType(otServerConfig, NetworkData::ServiceConfig::ServerConfig);
387
388 /**
389 * @}
390 */
391
392 } // namespace ot
393
394 #endif // NETWORK_DATA_TYPES_HPP_
395