• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2016, 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 manipulating Thread Network Data managed by the Thread Leader.
32  */
33 
34 #ifndef NETWORK_DATA_LEADER_HPP_
35 #define NETWORK_DATA_LEADER_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <stdint.h>
40 
41 #include "coap/coap.hpp"
42 #include "common/const_cast.hpp"
43 #include "common/timer.hpp"
44 #include "net/ip6_address.hpp"
45 #include "thread/mle_router.hpp"
46 #include "thread/network_data.hpp"
47 
48 namespace ot {
49 
50 namespace NetworkData {
51 
52 /**
53  * @addtogroup core-netdata-leader
54  *
55  * @brief
56  *   This module includes definitions for manipulating Thread Network Data managed by the Thread Leader.
57  *
58  * @{
59  *
60  */
61 
62 /**
63  * This class implements the Thread Network Data maintained by the Leader.
64  *
65  */
66 class LeaderBase : public MutableNetworkData
67 {
68 public:
69     /**
70      * This constructor initializes the object.
71      *
72      * @param[in]  aInstance     A reference to the OpenThread instance.
73      *
74      */
LeaderBase(Instance & aInstance)75     explicit LeaderBase(Instance &aInstance)
76         : MutableNetworkData(aInstance, mTlvBuffer, 0, sizeof(mTlvBuffer))
77     {
78         Reset();
79     }
80 
81     /**
82      * This method reset the Thread Network Data.
83      *
84      */
85     void Reset(void);
86 
87     /**
88      * This method returns the Data Version value for a type (full set or stable subset).
89      *
90      * @param[in] aType   The Network Data type (full set or stable subset).
91      *
92      * @returns The Data Version value for @p aType.
93      *
94      */
GetVersion(Type aType) const95     uint8_t GetVersion(Type aType) const { return (aType == kFullSet) ? mVersion : mStableVersion; }
96 
97     /**
98      * This method retrieves the 6LoWPAN Context information based on a given IPv6 address.
99      *
100      * @param[in]   aAddress  A reference to an IPv6 address.
101      * @param[out]  aContext  A reference to 6LoWPAN Context information.
102      *
103      * @retval kErrorNone       Successfully retrieved 6LoWPAN Context information.
104      * @retval kErrorNotFound   Could not find the 6LoWPAN Context information.
105      *
106      */
107     Error GetContext(const Ip6::Address &aAddress, Lowpan::Context &aContext) const;
108 
109     /**
110      * This method retrieves the 6LoWPAN Context information based on a given Context ID.
111      *
112      * @param[in]   aContextId  The Context ID value.
113      * @param[out]  aContext    A reference to the 6LoWPAN Context information.
114      *
115      * @retval kErrorNone       Successfully retrieved 6LoWPAN Context information.
116      * @retval kErrorNotFound   Could not find the 6LoWPAN Context information.
117      *
118      */
119     Error GetContext(uint8_t aContextId, Lowpan::Context &aContext) const;
120 
121     /**
122      * This method indicates whether or not the given IPv6 address is on-mesh.
123      *
124      * @param[in]  aAddress  A reference to an IPv6 address.
125      *
126      * @retval TRUE   If @p aAddress is on-link.
127      * @retval FALSE  If @p aAddress if not on-link.
128      *
129      */
130     bool IsOnMesh(const Ip6::Address &aAddress) const;
131 
132     /**
133      * This method performs a route lookup using the Network Data.
134      *
135      * @param[in]   aSource             A reference to the IPv6 source address.
136      * @param[in]   aDestination        A reference to the IPv6 destination address.
137      * @param[out]  aPrefixMatchLength  A pointer to output the longest prefix match length in bits.
138      * @param[out]  aRloc16             A pointer to the RLOC16 for the selected route.
139      *
140      * @retval kErrorNone      Successfully found a route.
141      * @retval kErrorNoRoute   No valid route was found.
142      *
143      */
144     Error RouteLookup(const Ip6::Address &aSource,
145                       const Ip6::Address &aDestination,
146                       uint8_t *           aPrefixMatchLength,
147                       uint16_t *          aRloc16) const;
148 
149     /**
150      * This method is used by non-Leader devices to set newly received Network Data from the Leader.
151      *
152      * @param[in]  aVersion        The Version value.
153      * @param[in]  aStableVersion  The Stable Version value.
154      * @param[in]  aType           The Network Data type to set, the full set or stable subset.
155      * @param[in]  aMessage        A reference to the MLE message.
156      * @param[in]  aMessageOffset  The offset in @p aMessage for the Network Data TLV.
157      *
158      * @retval kErrorNone   Successfully set the network data.
159      * @retval kErrorParse  Network Data TLV in @p aMessage is not valid.
160      *
161      */
162     Error SetNetworkData(uint8_t        aVersion,
163                          uint8_t        aStableVersion,
164                          Type           aType,
165                          const Message &aMessage,
166                          uint16_t       aMessageOffset);
167 
168     /**
169      * This method returns a pointer to the Commissioning Data.
170      *
171      * @returns A pointer to the Commissioning Data or `nullptr` if no Commissioning Data exists.
172      *
173      */
GetCommissioningData(void)174     CommissioningDataTlv *GetCommissioningData(void) { return AsNonConst(AsConst(this)->GetCommissioningData()); }
175 
176     /**
177      * This method returns a pointer to the Commissioning Data.
178      *
179      * @returns A pointer to the Commissioning Data or `nullptr` if no Commissioning Data exists.
180      *
181      */
182     const CommissioningDataTlv *GetCommissioningData(void) const;
183 
184     /**
185      * This method returns a pointer to the Commissioning Data Sub-TLV.
186      *
187      * @param[in]  aType  The TLV type value.
188      *
189      * @returns A pointer to the Commissioning Data Sub-TLV or `nullptr` if no Sub-TLV exists.
190      *
191      */
GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aType)192     MeshCoP::Tlv *GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aType)
193     {
194         return AsNonConst(AsConst(this)->GetCommissioningDataSubTlv(aType));
195     }
196 
197     /**
198      * This method returns a pointer to the Commissioning Data Sub-TLV.
199      *
200      * @param[in]  aType  The TLV type value.
201      *
202      * @returns A pointer to the Commissioning Data Sub-TLV or `nullptr` if no Sub-TLV exists.
203      *
204      */
205     const MeshCoP::Tlv *GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aType) const;
206 
207     /**
208      * This method indicates whether or not the Commissioning Data TLV indicates Joining is enabled.
209      *
210      * Joining is enabled if a Border Agent Locator TLV exist and the Steering Data TLV is non-zero.
211      *
212      * @returns TRUE if the Commissioning Data TLV says Joining is enabled, FALSE otherwise.
213      *
214      */
215     bool IsJoiningEnabled(void) const;
216 
217     /**
218      * This method adds Commissioning Data to the Thread Network Data.
219      *
220      * @param[in]  aValue        A pointer to the Commissioning Data value.
221      * @param[in]  aValueLength  The length of @p aValue.
222      *
223      * @retval kErrorNone     Successfully added the Commissioning Data.
224      * @retval kErrorNoBufs   Insufficient space to add the Commissioning Data.
225      *
226      */
227     Error SetCommissioningData(const uint8_t *aValue, uint8_t aValueLength);
228 
229     /**
230      * This method checks if the steering data includes a Joiner.
231      *
232      * @param[in]  aEui64             A reference to the Joiner's IEEE EUI-64.
233      *
234      * @retval kErrorNone          @p aEui64 is in the bloom filter.
235      * @retval kErrorInvalidState  No steering data present.
236      * @retval kErrorNotFound      @p aEui64 is not in the bloom filter.
237      *
238      */
239     Error SteeringDataCheckJoiner(const Mac::ExtAddress &aEui64) const;
240 
241     /**
242      * This method checks if the steering data includes a Joiner with a given discerner value.
243      *
244      * @param[in]  aDiscerner         A reference to the Joiner Discerner.
245      *
246      * @retval kErrorNone          @p aDiscerner is in the bloom filter.
247      * @retval kErrorInvalidState  No steering data present.
248      * @retval kErrorNotFound      @p aDiscerner is not in the bloom filter.
249      *
250      */
251     Error SteeringDataCheckJoiner(const MeshCoP::JoinerDiscerner &aDiscerner) const;
252 
253     /**
254      * This method gets the Service ID for the specified service.
255      *
256      * @param[in]  aEnterpriseNumber  Enterprise Number (IANA-assigned) for Service TLV
257      * @param[in]  aServiceData       The Service Data.
258      * @param[in]  aServerStable      The Stable flag value for Server TLV.
259      * @param[out] aServiceId         A reference where to put the Service ID.
260      *
261      * @retval kErrorNone       Successfully got the Service ID.
262      * @retval kErrorNotFound   The specified service was not found.
263      *
264      */
265     Error GetServiceId(uint32_t           aEnterpriseNumber,
266                        const ServiceData &aServiceData,
267                        bool               aServerStable,
268                        uint8_t &          aServiceId) const;
269 
270     /**
271      * This methods gets the preferred NAT64 prefix from network data.
272      *
273      * The returned prefix is the highest preference external route entry in Network Data with NAT64 flag set. If there
274      * are multiple such entries the first one is returned.
275      *
276      * @param[out] aConfig      A reference to an `ExternalRouteConfig` to return the prefix.
277      *
278      * @retval kErrorNone       Found the NAT64 prefix and updated @p aConfig.
279      * @retval kErrorNotFound   Could not find any NAT64 entry.
280      *
281      */
282     Error GetPreferredNat64Prefix(ExternalRouteConfig &aConfig) const;
283 
284 protected:
285     uint8_t mStableVersion;
286     uint8_t mVersion;
287 
288 private:
289     using FilterIndexes = MeshCoP::SteeringData::HashBitIndexes;
290 
291     const PrefixTlv *FindNextMatchingPrefix(const Ip6::Address &aAddress, const PrefixTlv *aPrevTlv) const;
292 
293     void RemoveCommissioningData(void);
294 
295     Error ExternalRouteLookup(uint8_t             aDomainId,
296                               const Ip6::Address &aDestination,
297                               uint8_t *           aPrefixMatchLength,
298                               uint16_t *          aRloc16) const;
299     Error DefaultRouteLookup(const PrefixTlv &aPrefix, uint16_t *aRloc16) const;
300     Error SteeringDataCheck(const FilterIndexes &aFilterIndexes) const;
301 
302     uint8_t mTlvBuffer[kMaxSize];
303 };
304 
305 /**
306  * @}
307  */
308 
309 } // namespace NetworkData
310 } // namespace ot
311 
312 #if OPENTHREAD_MTD
313 namespace ot {
314 namespace NetworkData {
315 class Leader : public LeaderBase
316 {
317 public:
318     using LeaderBase::LeaderBase;
319 };
320 } // namespace NetworkData
321 } // namespace ot
322 #elif OPENTHREAD_FTD
323 #include "network_data_leader_ftd.hpp"
324 #else
325 #error "Please define OPENTHREAD_MTD=1 or OPENTHREAD_FTD=1"
326 #endif
327 
328 #endif // NETWORK_DATA_LEADER_HPP_
329