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