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