blob: 54765ef7340530175c75c60707d5a30e7d8b194e [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_HPP_
#define NETWORK_DATA_LEADER_HPP_
#include "openthread-core-config.h"
#include <stdint.h>
#include "coap/coap.hpp"
#include "common/const_cast.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 LeaderBase : public MutableNetworkData
{
public:
/**
* This constructor initializes the object.
*
* @param[in] aInstance A reference to the OpenThread instance.
*
*/
explicit LeaderBase(Instance &aInstance)
: MutableNetworkData(aInstance, mTlvBuffer, 0, sizeof(mTlvBuffer))
{
Reset();
}
/**
* This method reset the Thread Network Data.
*
*/
void Reset(void);
/**
* This method returns the Data Version value for a type (full set or stable subset).
*
* @param[in] aType The Network Data type (full set or stable subset).
*
* @returns The Data Version value for @p aType.
*
*/
uint8_t GetVersion(Type aType) const { return (aType == kFullSet) ? mVersion : mStableVersion; }
/**
* This method retrieves the 6LoWPAN Context information based on a given IPv6 address.
*
* @param[in] aAddress A reference to an IPv6 address.
* @param[out] aContext A reference to 6LoWPAN Context information.
*
* @retval kErrorNone Successfully retrieved 6LoWPAN Context information.
* @retval kErrorNotFound Could not find the 6LoWPAN Context information.
*
*/
Error GetContext(const Ip6::Address &aAddress, Lowpan::Context &aContext) const;
/**
* This method retrieves the 6LoWPAN Context information based on a given Context ID.
*
* @param[in] aContextId The Context ID value.
* @param[out] aContext A reference to the 6LoWPAN Context information.
*
* @retval kErrorNone Successfully retrieved 6LoWPAN Context information.
* @retval kErrorNotFound Could not find the 6LoWPAN Context information.
*
*/
Error GetContext(uint8_t aContextId, Lowpan::Context &aContext) const;
/**
* This method indicates whether or not the given IPv6 address is on-mesh.
*
* @param[in] aAddress A reference to an IPv6 address.
*
* @retval TRUE If @p aAddress is on-link.
* @retval FALSE If @p aAddress if not on-link.
*
*/
bool IsOnMesh(const Ip6::Address &aAddress) const;
/**
* This method performs a route lookup using the Network Data.
*
* @param[in] aSource A reference to the IPv6 source address.
* @param[in] aDestination A reference to the IPv6 destination address.
* @param[out] aPrefixMatchLength A pointer to output the longest prefix match length in bits.
* @param[out] aRloc16 A pointer to the RLOC16 for the selected route.
*
* @retval kErrorNone Successfully found a route.
* @retval kErrorNoRoute No valid route was found.
*
*/
Error RouteLookup(const Ip6::Address &aSource,
const Ip6::Address &aDestination,
uint8_t * aPrefixMatchLength,
uint16_t * aRloc16) const;
/**
* This method is used by non-Leader devices to set newly received Network Data from the Leader.
*
* @param[in] aVersion The Version value.
* @param[in] aStableVersion The Stable Version value.
* @param[in] aType The Network Data type to set, the full set or stable subset.
* @param[in] aMessage A reference to the MLE message.
* @param[in] aMessageOffset The offset in @p aMessage for the Network Data TLV.
*
* @retval kErrorNone Successfully set the network data.
* @retval kErrorParse Network Data TLV in @p aMessage is not valid.
*
*/
Error SetNetworkData(uint8_t aVersion,
uint8_t aStableVersion,
Type aType,
const Message &aMessage,
uint16_t aMessageOffset);
/**
* This method returns a pointer to the Commissioning Data.
*
* @returns A pointer to the Commissioning Data or `nullptr` if no Commissioning Data exists.
*
*/
CommissioningDataTlv *GetCommissioningData(void) { return AsNonConst(AsConst(this)->GetCommissioningData()); }
/**
* This method returns a pointer to the Commissioning Data.
*
* @returns A pointer to the Commissioning Data or `nullptr` if no Commissioning Data exists.
*
*/
const CommissioningDataTlv *GetCommissioningData(void) const;
/**
* This method returns a pointer to the Commissioning Data Sub-TLV.
*
* @param[in] aType The TLV type value.
*
* @returns A pointer to the Commissioning Data Sub-TLV or `nullptr` if no Sub-TLV exists.
*
*/
MeshCoP::Tlv *GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aType)
{
return AsNonConst(AsConst(this)->GetCommissioningDataSubTlv(aType));
}
/**
* This method returns a pointer to the Commissioning Data Sub-TLV.
*
* @param[in] aType The TLV type value.
*
* @returns A pointer to the Commissioning Data Sub-TLV or `nullptr` if no Sub-TLV exists.
*
*/
const MeshCoP::Tlv *GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aType) const;
/**
* This method indicates whether or not the Commissioning Data TLV indicates Joining is enabled.
*
* Joining is enabled if a Border Agent Locator TLV exist and the Steering Data TLV is non-zero.
*
* @returns TRUE if the Commissioning Data TLV says Joining is enabled, FALSE otherwise.
*
*/
bool IsJoiningEnabled(void) const;
/**
* This method adds Commissioning Data to the Thread Network Data.
*
* @param[in] aValue A pointer to the Commissioning Data value.
* @param[in] aValueLength The length of @p aValue.
*
* @retval kErrorNone Successfully added the Commissioning Data.
* @retval kErrorNoBufs Insufficient space to add the Commissioning Data.
*
*/
Error SetCommissioningData(const uint8_t *aValue, uint8_t aValueLength);
/**
* This method checks if the steering data includes a Joiner.
*
* @param[in] aEui64 A reference to the Joiner's IEEE EUI-64.
*
* @retval kErrorNone @p aEui64 is in the bloom filter.
* @retval kErrorInvalidState No steering data present.
* @retval kErrorNotFound @p aEui64 is not in the bloom filter.
*
*/
Error SteeringDataCheckJoiner(const Mac::ExtAddress &aEui64) const;
/**
* This method checks if the steering data includes a Joiner with a given discerner value.
*
* @param[in] aDiscerner A reference to the Joiner Discerner.
*
* @retval kErrorNone @p aDiscerner is in the bloom filter.
* @retval kErrorInvalidState No steering data present.
* @retval kErrorNotFound @p aDiscerner is not in the bloom filter.
*
*/
Error SteeringDataCheckJoiner(const MeshCoP::JoinerDiscerner &aDiscerner) const;
/**
* This method gets the Service ID for the specified service.
*
* @param[in] aEnterpriseNumber Enterprise Number (IANA-assigned) for Service TLV
* @param[in] aServiceData The Service Data.
* @param[in] aServerStable The Stable flag value for Server TLV.
* @param[out] aServiceId A reference where to put the Service ID.
*
* @retval kErrorNone Successfully got the Service ID.
* @retval kErrorNotFound The specified service was not found.
*
*/
Error GetServiceId(uint32_t aEnterpriseNumber,
const ServiceData &aServiceData,
bool aServerStable,
uint8_t & aServiceId) const;
/**
* This methods gets the preferred NAT64 prefix from network data.
*
* The returned prefix is the highest preference external route entry in Network Data with NAT64 flag set. If there
* are multiple such entries the first one is returned.
*
* @param[out] aConfig A reference to an `ExternalRouteConfig` to return the prefix.
*
* @retval kErrorNone Found the NAT64 prefix and updated @p aConfig.
* @retval kErrorNotFound Could not find any NAT64 entry.
*
*/
Error GetPreferredNat64Prefix(ExternalRouteConfig &aConfig) const;
protected:
uint8_t mStableVersion;
uint8_t mVersion;
private:
using FilterIndexes = MeshCoP::SteeringData::HashBitIndexes;
const PrefixTlv *FindNextMatchingPrefix(const Ip6::Address &aAddress, const PrefixTlv *aPrevTlv) const;
void RemoveCommissioningData(void);
Error ExternalRouteLookup(uint8_t aDomainId,
const Ip6::Address &aDestination,
uint8_t * aPrefixMatchLength,
uint16_t * aRloc16) const;
Error DefaultRouteLookup(const PrefixTlv &aPrefix, uint16_t *aRloc16) const;
Error SteeringDataCheck(const FilterIndexes &aFilterIndexes) const;
uint8_t mTlvBuffer[kMaxSize];
};
/**
* @}
*/
} // namespace NetworkData
} // namespace ot
#if OPENTHREAD_MTD
namespace ot {
namespace NetworkData {
class Leader : public LeaderBase
{
public:
using LeaderBase::LeaderBase;
};
} // namespace NetworkData
} // namespace ot
#elif OPENTHREAD_FTD
#include "network_data_leader_ftd.hpp"
#else
#error "Please define OPENTHREAD_MTD=1 or OPENTHREAD_FTD=1"
#endif
#endif // NETWORK_DATA_LEADER_HPP_