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