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