• 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_FTD_HPP_
35 #define NETWORK_DATA_LEADER_FTD_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #if OPENTHREAD_FTD
40 
41 #include <stdint.h>
42 
43 #include "coap/coap.hpp"
44 #include "common/non_copyable.hpp"
45 #include "common/timer.hpp"
46 #include "net/ip6_address.hpp"
47 #include "thread/mle_router.hpp"
48 #include "thread/network_data.hpp"
49 
50 namespace ot {
51 
52 namespace NetworkData {
53 
54 /**
55  * @addtogroup core-netdata-leader
56  *
57  * @brief
58  *   This module includes definitions for manipulating Thread Network Data managed by the Thread Leader.
59  *
60  * @{
61  *
62  */
63 
64 /**
65  * This class implements the Thread Network Data maintained by the Leader.
66  *
67  */
68 class Leader : public LeaderBase, private NonCopyable
69 {
70 public:
71     /**
72      * This enumeration defines the match mode constants to compare two RLOC16 values.
73      *
74      */
75     enum MatchMode : uint8_t
76     {
77         kMatchModeRloc16,   ///< Perform exact RLOC16 match.
78         kMatchModeRouterId, ///< Perform Router ID match (match the router and any of its children).
79     };
80 
81     /**
82      * This constructor initializes the object.
83      *
84      * @param[in]  aInstance     A reference to the OpenThread instance.
85      *
86      */
87     explicit Leader(Instance &aInstance);
88 
89     /**
90      * This method reset the Thread Network Data.
91      *
92      */
93     void Reset(void);
94 
95     /**
96      * This method starts the Leader services.
97      *
98      * The start mode indicates whether device is starting normally as leader or restoring its role as leader after
99      * reset. In the latter case, we do not accept any new registrations (`HandleServerData()`) and wait for
100      * `HandleNetworkDataRestoredAfterReset()` to indicate that the leader has successfully recovered the Network Data
101      * before allowing new Network Data registrations.
102      *
103      * @param[in] aStartMode   The start mode.
104      *
105      */
106     void Start(Mle::LeaderStartMode aStartMode);
107 
108     /**
109      * This method stops the Leader services.
110      *
111      */
112     void Stop(void);
113 
114     /**
115      * This method increments the Thread Network Data version.
116      *
117      */
118     void IncrementVersion(void);
119 
120     /**
121      * This method increments both the Thread Network Data version and stable version.
122      *
123      */
124     void IncrementVersionAndStableVersion(void);
125 
126     /**
127      * This method returns CONTEXT_ID_RESUSE_DELAY value.
128      *
129      * @returns The CONTEXT_ID_REUSE_DELAY value.
130      *
131      */
GetContextIdReuseDelay(void) const132     uint32_t GetContextIdReuseDelay(void) const { return mContextIdReuseDelay; }
133 
134     /**
135      * This method sets CONTEXT_ID_RESUSE_DELAY value.
136      *
137      * @warning This method should only be used for testing.
138      *
139      * @param[in]  aDelay  The CONTEXT_ID_REUSE_DELAY value.
140      *
141      */
SetContextIdReuseDelay(uint32_t aDelay)142     void SetContextIdReuseDelay(uint32_t aDelay) { mContextIdReuseDelay = aDelay; }
143 
144     /**
145      * This method removes Network Data entries matching with a given RLOC16.
146      *
147      * @param[in]  aRloc16    A RLOC16 value.
148      * @param[in]  aMatchMode A match mode (@sa MatchMode).
149      *
150      */
151     void RemoveBorderRouter(uint16_t aRloc16, MatchMode aMatchMode);
152 
153     /**
154      * This method synchronizes internal 6LoWPAN Context ID Set with recently obtained Thread Network Data.
155      *
156      * Note that this method should be called only by the Leader once after reset.
157      *
158      */
159     void HandleNetworkDataRestoredAfterReset(void);
160 
161     /**
162      * This method scans network data for given Service ID and returns pointer to the respective TLV, if present.
163      *
164      * @param aServiceId Service ID to look for.
165      * @return Pointer to the Service TLV for given Service ID, or nullptr if not present.
166      *
167      */
168     const ServiceTlv *FindServiceById(uint8_t aServiceId) const;
169 
170     /**
171      * This method sends SVR_DATA.ntf message for any stale child entries that exist in the network data.
172      *
173      * @param[in]  aHandler  A function pointer that is called when the transaction ends.
174      * @param[in]  aContext  A pointer to arbitrary context information.
175      *
176      * @retval kErrorNone      A stale child entry was found and successfully enqueued a SVR_DATA.ntf message.
177      * @retval kErrorNoBufs    A stale child entry was found, but insufficient message buffers were available.
178      * @retval kErrorNotFound  No stale child entries were found.
179      *
180      */
181     Error RemoveStaleChildEntries(Coap::ResponseHandler aHandler, void *aContext);
182 
183 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
184     /**
185      * This method indicates whether a given Prefix can act as a valid OMR prefix and exists in the network data.
186      *
187      * @param[in]  aPrefix   The OMR prefix to check.
188      *
189      * @retval TRUE  If @p aPrefix is a valid OMR prefix and Network Data contains @p aPrefix.
190      * @retval FALSE Otherwise.
191      *
192      */
193     bool ContainsOmrPrefix(const Ip6::Prefix &aPrefix);
194 #endif
195 
196 private:
197     class ChangedFlags
198     {
199     public:
ChangedFlags(void)200         ChangedFlags(void)
201             : mChanged(false)
202             , mStableChanged(false)
203         {
204         }
205 
Update(const NetworkDataTlv & aTlv)206         void Update(const NetworkDataTlv &aTlv)
207         {
208             mChanged       = true;
209             mStableChanged = (mStableChanged || aTlv.IsStable());
210         }
211 
DidChange(void) const212         bool DidChange(void) const { return mChanged; }
DidStableChange(void) const213         bool DidStableChange(void) const { return mStableChanged; }
214 
215     private:
216         bool mChanged;       // Any (stable or not) network data change (add/remove).
217         bool mStableChanged; // Stable network data change (add/remove).
218     };
219 
220     enum UpdateStatus : uint8_t
221     {
222         kTlvRemoved, // TLV contained no sub TLVs and therefore is removed.
223         kTlvUpdated, // TLV stable flag is updated based on its sub TLVs.
224     };
225 
226     static void HandleServerData(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
227     void        HandleServerData(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
228 
229     static void HandleTimer(Timer &aTimer);
230     void        HandleTimer(void);
231 
232     void RegisterNetworkData(uint16_t aRloc16, const NetworkData &aNetworkData);
233 
234     Error AddPrefix(const PrefixTlv &aPrefix, ChangedFlags &aChangedFlags);
235     Error AddHasRoute(const HasRouteTlv &aHasRoute, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags);
236     Error AddBorderRouter(const BorderRouterTlv &aBorderRouter, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags);
237     Error AddService(const ServiceTlv &aService, ChangedFlags &aChangedFlags);
238     Error AddServer(const ServerTlv &aServer, ServiceTlv &aDstService, ChangedFlags &aChangedFlags);
239 
240     Error AllocateServiceId(uint8_t &aServiceId) const;
241 
242     Error AllocateContextId(uint8_t &aContextId);
243     void  FreeContextId(uint8_t aContextId);
244     void  StartContextReuseTimer(uint8_t aContextId);
245     void  StopContextReuseTimer(uint8_t aContextId);
246 
247     void RemoveContext(uint8_t aContextId);
248     void RemoveContext(PrefixTlv &aPrefix, uint8_t aContextId);
249 
250     void RemoveCommissioningData(void);
251 
252     void RemoveRloc(uint16_t aRloc16, MatchMode aMatchMode, ChangedFlags &aChangedFlags);
253     void RemoveRloc(uint16_t           aRloc16,
254                     MatchMode          aMatchMode,
255                     const NetworkData &aExcludeNetworkData,
256                     ChangedFlags &     aChangedFlags);
257     void RemoveRlocInPrefix(PrefixTlv &      aPrefix,
258                             uint16_t         aRloc16,
259                             MatchMode        aMatchMode,
260                             const PrefixTlv *aExcludePrefix,
261                             ChangedFlags &   aChangedFlags);
262     void RemoveRlocInService(ServiceTlv &      aService,
263                              uint16_t          aRloc16,
264                              MatchMode         aMatchMode,
265                              const ServiceTlv *aExcludeService,
266                              ChangedFlags &    aChangedFlags);
267     void RemoveRlocInHasRoute(PrefixTlv &      aPrefix,
268                               HasRouteTlv &    aHasRoute,
269                               uint16_t         aRloc16,
270                               MatchMode        aMatchMode,
271                               const PrefixTlv *aExcludePrefix,
272                               ChangedFlags &   aChangedFlags);
273     void RemoveRlocInBorderRouter(PrefixTlv &      aPrefix,
274                                   BorderRouterTlv &aBorderRouter,
275                                   uint16_t         aRloc16,
276                                   MatchMode        aMatchMode,
277                                   const PrefixTlv *aExcludePrefix,
278                                   ChangedFlags &   aChangedFlags);
279 
280     static bool RlocMatch(uint16_t aFirstRloc16, uint16_t aSecondRloc16, MatchMode aMatchMode);
281 
282     static Error Validate(const NetworkData &aNetworkData, uint16_t aRloc16);
283     static Error ValidatePrefix(const PrefixTlv &aPrefix, uint16_t aRloc16);
284     static Error ValidateService(const ServiceTlv &aService, uint16_t aRloc16);
285 
286     static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const HasRouteEntry &aEntry);
287     static bool ContainsMatchingEntry(const HasRouteTlv *aHasRoute, const HasRouteEntry &aEntry);
288     static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const BorderRouterEntry &aEntry);
289     static bool ContainsMatchingEntry(const BorderRouterTlv *aBorderRouter, const BorderRouterEntry &aEntry);
290     static bool ContainsMatchingServer(const ServiceTlv *aService, const ServerTlv &aServer);
291 
292     UpdateStatus UpdatePrefix(PrefixTlv &aPrefix);
293     UpdateStatus UpdateService(ServiceTlv &aService);
294     UpdateStatus UpdateTlv(NetworkDataTlv &aTlv, const NetworkDataTlv *aSubTlvs);
295 
296     static void HandleCommissioningSet(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
297     void        HandleCommissioningSet(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
298 
299     static void HandleCommissioningGet(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
300     void        HandleCommissioningGet(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
301 
302     void SendCommissioningGetResponse(const Coap::Message &   aRequest,
303                                       uint16_t                aLength,
304                                       const Ip6::MessageInfo &aMessageInfo);
305     void SendCommissioningSetResponse(const Coap::Message &    aRequest,
306                                       const Ip6::MessageInfo & aMessageInfo,
307                                       MeshCoP::StateTlv::State aState);
308     void IncrementVersions(bool aIncludeStable);
309     void IncrementVersions(const ChangedFlags &aFlags);
310 
311     static constexpr uint8_t  kMinContextId        = 1;            // Minimum Context ID (0 is used for Mesh Local)
312     static constexpr uint8_t  kNumContextIds       = 15;           // Maximum Context ID
313     static constexpr uint32_t kContextIdReuseDelay = 48 * 60 * 60; // in seconds
314     static constexpr uint32_t kStateUpdatePeriod   = 60 * 1000;    // State update period in milliseconds
315     static constexpr uint32_t kMaxNetDataSyncWait  = 60 * 1000;    // Maximum time to wait for netdata sync.
316 
317     bool       mWaitingForNetDataSync;
318     uint16_t   mContextUsed;
319     TimeMilli  mContextLastUsed[kNumContextIds];
320     uint32_t   mContextIdReuseDelay;
321     TimerMilli mTimer;
322 
323     Coap::Resource mServerData;
324 
325     Coap::Resource mCommissioningDataGet;
326     Coap::Resource mCommissioningDataSet;
327 };
328 
329 /**
330  * @}
331  */
332 
333 } // namespace NetworkData
334 } // namespace ot
335 
336 #endif // OPENTHREAD_FTD
337 
338 #endif // NETWORK_DATA_LEADER_FTD_HPP_
339