blob: 1ca969f6776f6c366d47a2eaf8df2ea6c8cd2067 [file] [log] [blame]
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for manipulating Thread Network Data managed by the Thread Leader.
*/
#ifndef NETWORK_DATA_LEADER_FTD_HPP_
#define NETWORK_DATA_LEADER_FTD_HPP_
#include "openthread-core-config.h"
#if OPENTHREAD_FTD
#include <stdint.h>
#include "coap/coap.hpp"
#include "common/non_copyable.hpp"
#include "common/timer.hpp"
#include "net/ip6_address.hpp"
#include "thread/mle_router.hpp"
#include "thread/network_data.hpp"
namespace ot {
namespace NetworkData {
/**
* @addtogroup core-netdata-leader
*
* @brief
* This module includes definitions for manipulating Thread Network Data managed by the Thread Leader.
*
* @{
*
*/
/**
* This class implements the Thread Network Data maintained by the Leader.
*
*/
class Leader : public LeaderBase, private NonCopyable
{
public:
/**
* This enumeration defines the match mode constants to compare two RLOC16 values.
*
*/
enum MatchMode : uint8_t
{
kMatchModeRloc16, ///< Perform exact RLOC16 match.
kMatchModeRouterId, ///< Perform Router ID match (match the router and any of its children).
};
/**
* This constructor initializes the object.
*
* @param[in] aInstance A reference to the OpenThread instance.
*
*/
explicit Leader(Instance &aInstance);
/**
* This method reset the Thread Network Data.
*
*/
void Reset(void);
/**
* This method starts the Leader services.
*
* The start mode indicates whether device is starting normally as leader or restoring its role as leader after
* reset. In the latter case, we do not accept any new registrations (`HandleServerData()`) and wait for
* `HandleNetworkDataRestoredAfterReset()` to indicate that the leader has successfully recovered the Network Data
* before allowing new Network Data registrations.
*
* @param[in] aStartMode The start mode.
*
*/
void Start(Mle::LeaderStartMode aStartMode);
/**
* This method stops the Leader services.
*
*/
void Stop(void);
/**
* This method increments the Thread Network Data version.
*
*/
void IncrementVersion(void);
/**
* This method increments both the Thread Network Data version and stable version.
*
*/
void IncrementVersionAndStableVersion(void);
/**
* This method returns CONTEXT_ID_RESUSE_DELAY value.
*
* @returns The CONTEXT_ID_REUSE_DELAY value.
*
*/
uint32_t GetContextIdReuseDelay(void) const { return mContextIdReuseDelay; }
/**
* This method sets CONTEXT_ID_RESUSE_DELAY value.
*
* @warning This method should only be used for testing.
*
* @param[in] aDelay The CONTEXT_ID_REUSE_DELAY value.
*
*/
void SetContextIdReuseDelay(uint32_t aDelay) { mContextIdReuseDelay = aDelay; }
/**
* This method removes Network Data entries matching with a given RLOC16.
*
* @param[in] aRloc16 A RLOC16 value.
* @param[in] aMatchMode A match mode (@sa MatchMode).
*
*/
void RemoveBorderRouter(uint16_t aRloc16, MatchMode aMatchMode);
/**
* This method synchronizes internal 6LoWPAN Context ID Set with recently obtained Thread Network Data.
*
* Note that this method should be called only by the Leader once after reset.
*
*/
void HandleNetworkDataRestoredAfterReset(void);
/**
* This method scans network data for given Service ID and returns pointer to the respective TLV, if present.
*
* @param aServiceId Service ID to look for.
* @return Pointer to the Service TLV for given Service ID, or nullptr if not present.
*
*/
const ServiceTlv *FindServiceById(uint8_t aServiceId) const;
/**
* This method sends SVR_DATA.ntf message for any stale child entries that exist in the network data.
*
* @param[in] aHandler A function pointer that is called when the transaction ends.
* @param[in] aContext A pointer to arbitrary context information.
*
* @retval kErrorNone A stale child entry was found and successfully enqueued a SVR_DATA.ntf message.
* @retval kErrorNoBufs A stale child entry was found, but insufficient message buffers were available.
* @retval kErrorNotFound No stale child entries were found.
*
*/
Error RemoveStaleChildEntries(Coap::ResponseHandler aHandler, void *aContext);
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
/**
* This method indicates whether a given Prefix can act as a valid OMR prefix and exists in the network data.
*
* @param[in] aPrefix The OMR prefix to check.
*
* @retval TRUE If @p aPrefix is a valid OMR prefix and Network Data contains @p aPrefix.
* @retval FALSE Otherwise.
*
*/
bool ContainsOmrPrefix(const Ip6::Prefix &aPrefix);
#endif
private:
class ChangedFlags
{
public:
ChangedFlags(void)
: mChanged(false)
, mStableChanged(false)
{
}
void Update(const NetworkDataTlv &aTlv)
{
mChanged = true;
mStableChanged = (mStableChanged || aTlv.IsStable());
}
bool DidChange(void) const { return mChanged; }
bool DidStableChange(void) const { return mStableChanged; }
private:
bool mChanged; // Any (stable or not) network data change (add/remove).
bool mStableChanged; // Stable network data change (add/remove).
};
enum UpdateStatus : uint8_t
{
kTlvRemoved, // TLV contained no sub TLVs and therefore is removed.
kTlvUpdated, // TLV stable flag is updated based on its sub TLVs.
};
static void HandleServerData(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void HandleServerData(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
static void HandleTimer(Timer &aTimer);
void HandleTimer(void);
void RegisterNetworkData(uint16_t aRloc16, const NetworkData &aNetworkData);
Error AddPrefix(const PrefixTlv &aPrefix, ChangedFlags &aChangedFlags);
Error AddHasRoute(const HasRouteTlv &aHasRoute, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags);
Error AddBorderRouter(const BorderRouterTlv &aBorderRouter, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags);
Error AddService(const ServiceTlv &aService, ChangedFlags &aChangedFlags);
Error AddServer(const ServerTlv &aServer, ServiceTlv &aDstService, ChangedFlags &aChangedFlags);
Error AllocateServiceId(uint8_t &aServiceId) const;
Error AllocateContextId(uint8_t &aContextId);
void FreeContextId(uint8_t aContextId);
void StartContextReuseTimer(uint8_t aContextId);
void StopContextReuseTimer(uint8_t aContextId);
void RemoveContext(uint8_t aContextId);
void RemoveContext(PrefixTlv &aPrefix, uint8_t aContextId);
void RemoveCommissioningData(void);
void RemoveRloc(uint16_t aRloc16, MatchMode aMatchMode, ChangedFlags &aChangedFlags);
void RemoveRloc(uint16_t aRloc16,
MatchMode aMatchMode,
const NetworkData &aExcludeNetworkData,
ChangedFlags & aChangedFlags);
void RemoveRlocInPrefix(PrefixTlv & aPrefix,
uint16_t aRloc16,
MatchMode aMatchMode,
const PrefixTlv *aExcludePrefix,
ChangedFlags & aChangedFlags);
void RemoveRlocInService(ServiceTlv & aService,
uint16_t aRloc16,
MatchMode aMatchMode,
const ServiceTlv *aExcludeService,
ChangedFlags & aChangedFlags);
void RemoveRlocInHasRoute(PrefixTlv & aPrefix,
HasRouteTlv & aHasRoute,
uint16_t aRloc16,
MatchMode aMatchMode,
const PrefixTlv *aExcludePrefix,
ChangedFlags & aChangedFlags);
void RemoveRlocInBorderRouter(PrefixTlv & aPrefix,
BorderRouterTlv &aBorderRouter,
uint16_t aRloc16,
MatchMode aMatchMode,
const PrefixTlv *aExcludePrefix,
ChangedFlags & aChangedFlags);
static bool RlocMatch(uint16_t aFirstRloc16, uint16_t aSecondRloc16, MatchMode aMatchMode);
static Error Validate(const NetworkData &aNetworkData, uint16_t aRloc16);
static Error ValidatePrefix(const PrefixTlv &aPrefix, uint16_t aRloc16);
static Error ValidateService(const ServiceTlv &aService, uint16_t aRloc16);
static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const HasRouteEntry &aEntry);
static bool ContainsMatchingEntry(const HasRouteTlv *aHasRoute, const HasRouteEntry &aEntry);
static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const BorderRouterEntry &aEntry);
static bool ContainsMatchingEntry(const BorderRouterTlv *aBorderRouter, const BorderRouterEntry &aEntry);
static bool ContainsMatchingServer(const ServiceTlv *aService, const ServerTlv &aServer);
UpdateStatus UpdatePrefix(PrefixTlv &aPrefix);
UpdateStatus UpdateService(ServiceTlv &aService);
UpdateStatus UpdateTlv(NetworkDataTlv &aTlv, const NetworkDataTlv *aSubTlvs);
static void HandleCommissioningSet(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void HandleCommissioningSet(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
static void HandleCommissioningGet(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void HandleCommissioningGet(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
void SendCommissioningGetResponse(const Coap::Message & aRequest,
uint16_t aLength,
const Ip6::MessageInfo &aMessageInfo);
void SendCommissioningSetResponse(const Coap::Message & aRequest,
const Ip6::MessageInfo & aMessageInfo,
MeshCoP::StateTlv::State aState);
void IncrementVersions(bool aIncludeStable);
void IncrementVersions(const ChangedFlags &aFlags);
static constexpr uint8_t kMinContextId = 1; // Minimum Context ID (0 is used for Mesh Local)
static constexpr uint8_t kNumContextIds = 15; // Maximum Context ID
static constexpr uint32_t kContextIdReuseDelay = 48 * 60 * 60; // in seconds
static constexpr uint32_t kStateUpdatePeriod = 60 * 1000; // State update period in milliseconds
static constexpr uint32_t kMaxNetDataSyncWait = 60 * 1000; // Maximum time to wait for netdata sync.
bool mWaitingForNetDataSync;
uint16_t mContextUsed;
TimeMilli mContextLastUsed[kNumContextIds];
uint32_t mContextIdReuseDelay;
TimerMilli mTimer;
Coap::Resource mServerData;
Coap::Resource mCommissioningDataGet;
Coap::Resource mCommissioningDataSet;
};
/**
* @}
*/
} // namespace NetworkData
} // namespace ot
#endif // OPENTHREAD_FTD
#endif // NETWORK_DATA_LEADER_FTD_HPP_