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 , mMaxLength(0) 78 { 79 Reset(); 80 } 81 82 /** 83 * This method reset the Thread Network Data. 84 * 85 */ 86 void Reset(void); 87 88 /** 89 * This method returns the maximum observed Network Data length since OT stack initialization or since the last 90 * call to `ResetMaxLength()`. 91 * 92 * @returns The maximum observed Network Data length (high water mark for Network Data length). 93 * 94 */ GetMaxLength(void) const95 uint8_t GetMaxLength(void) const { return mMaxLength; } 96 97 /** 98 * This method resets the tracked maximum Network Data Length. 99 * 100 * @sa GetMaxLength 101 * 102 */ ResetMaxLength(void)103 void ResetMaxLength(void) { mMaxLength = GetLength(); } 104 105 /** 106 * This method returns the Data Version value for a type (full set or stable subset). 107 * 108 * @param[in] aType The Network Data type (full set or stable subset). 109 * 110 * @returns The Data Version value for @p aType. 111 * 112 */ GetVersion(Type aType) const113 uint8_t GetVersion(Type aType) const { return (aType == kFullSet) ? mVersion : mStableVersion; } 114 115 /** 116 * This method retrieves the 6LoWPAN Context information based on a given IPv6 address. 117 * 118 * @param[in] aAddress A reference to an IPv6 address. 119 * @param[out] aContext A reference to 6LoWPAN Context information. 120 * 121 * @retval kErrorNone Successfully retrieved 6LoWPAN Context information. 122 * @retval kErrorNotFound Could not find the 6LoWPAN Context information. 123 * 124 */ 125 Error GetContext(const Ip6::Address &aAddress, Lowpan::Context &aContext) const; 126 127 /** 128 * This method retrieves the 6LoWPAN Context information based on a given Context ID. 129 * 130 * @param[in] aContextId The Context ID value. 131 * @param[out] aContext A reference to the 6LoWPAN Context information. 132 * 133 * @retval kErrorNone Successfully retrieved 6LoWPAN Context information. 134 * @retval kErrorNotFound Could not find the 6LoWPAN Context information. 135 * 136 */ 137 Error GetContext(uint8_t aContextId, Lowpan::Context &aContext) const; 138 139 /** 140 * This method indicates whether or not the given IPv6 address is on-mesh. 141 * 142 * @param[in] aAddress A reference to an IPv6 address. 143 * 144 * @retval TRUE If @p aAddress is on-link. 145 * @retval FALSE If @p aAddress if not on-link. 146 * 147 */ 148 bool IsOnMesh(const Ip6::Address &aAddress) const; 149 150 /** 151 * This method performs a route lookup using the Network Data. 152 * 153 * @param[in] aSource A reference to the IPv6 source address. 154 * @param[in] aDestination A reference to the IPv6 destination address. 155 * @param[out] aRloc16 A reference to return the RLOC16 for the selected route. 156 * 157 * @retval kErrorNone Successfully found a route. @p aRloc16 is updated. 158 * @retval kErrorNoRoute No valid route was found. 159 * 160 */ 161 Error RouteLookup(const Ip6::Address &aSource, const Ip6::Address &aDestination, uint16_t &aRloc16) const; 162 163 /** 164 * This method is used by non-Leader devices to set Network Data by reading it from a message from Leader. 165 * 166 * @param[in] aVersion The Version value. 167 * @param[in] aStableVersion The Stable Version value. 168 * @param[in] aType The Network Data type to set, the full set or stable subset. 169 * @param[in] aMessage A reference to the message. 170 * @param[in] aOffset The offset in @p aMessage pointing to start of Network Data. 171 * @param[in] aLength The length of Network Data. 172 * 173 * @retval kErrorNone Successfully set the network data. 174 * @retval kErrorParse Network Data in @p aMessage is not valid. 175 * 176 */ 177 Error SetNetworkData(uint8_t aVersion, 178 uint8_t aStableVersion, 179 Type aType, 180 const Message &aMessage, 181 uint16_t aOffset, 182 uint16_t aLength); 183 184 /** 185 * This method returns a pointer to the Commissioning Data. 186 * 187 * @returns A pointer to the Commissioning Data or `nullptr` if no Commissioning Data exists. 188 * 189 */ GetCommissioningData(void)190 CommissioningDataTlv *GetCommissioningData(void) { return AsNonConst(AsConst(this)->GetCommissioningData()); } 191 192 /** 193 * This method returns a pointer to the Commissioning Data. 194 * 195 * @returns A pointer to the Commissioning Data or `nullptr` if no Commissioning Data exists. 196 * 197 */ 198 const CommissioningDataTlv *GetCommissioningData(void) const; 199 200 /** 201 * This method returns a pointer to the Commissioning Data Sub-TLV. 202 * 203 * @param[in] aType The TLV type value. 204 * 205 * @returns A pointer to the Commissioning Data Sub-TLV or `nullptr` if no Sub-TLV exists. 206 * 207 */ GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aType)208 MeshCoP::Tlv *GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aType) 209 { 210 return AsNonConst(AsConst(this)->GetCommissioningDataSubTlv(aType)); 211 } 212 213 /** 214 * This method returns a pointer to the Commissioning Data Sub-TLV. 215 * 216 * @param[in] aType The TLV type value. 217 * 218 * @returns A pointer to the Commissioning Data Sub-TLV or `nullptr` if no Sub-TLV exists. 219 * 220 */ 221 const MeshCoP::Tlv *GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aType) const; 222 223 /** 224 * This method indicates whether or not the Commissioning Data TLV indicates Joining is enabled. 225 * 226 * Joining is enabled if a Border Agent Locator TLV exist and the Steering Data TLV is non-zero. 227 * 228 * @returns TRUE if the Commissioning Data TLV says Joining is enabled, FALSE otherwise. 229 * 230 */ 231 bool IsJoiningEnabled(void) const; 232 233 /** 234 * This method adds Commissioning Data to the Thread Network Data. 235 * 236 * @param[in] aValue A pointer to the Commissioning Data value. 237 * @param[in] aValueLength The length of @p aValue. 238 * 239 * @retval kErrorNone Successfully added the Commissioning Data. 240 * @retval kErrorNoBufs Insufficient space to add the Commissioning Data. 241 * 242 */ 243 Error SetCommissioningData(const uint8_t *aValue, uint8_t aValueLength); 244 245 /** 246 * This method checks if the steering data includes a Joiner. 247 * 248 * @param[in] aEui64 A reference to the Joiner's IEEE EUI-64. 249 * 250 * @retval kErrorNone @p aEui64 is in the bloom filter. 251 * @retval kErrorInvalidState No steering data present. 252 * @retval kErrorNotFound @p aEui64 is not in the bloom filter. 253 * 254 */ 255 Error SteeringDataCheckJoiner(const Mac::ExtAddress &aEui64) const; 256 257 /** 258 * This method checks if the steering data includes a Joiner with a given discerner value. 259 * 260 * @param[in] aDiscerner A reference to the Joiner Discerner. 261 * 262 * @retval kErrorNone @p aDiscerner is in the bloom filter. 263 * @retval kErrorInvalidState No steering data present. 264 * @retval kErrorNotFound @p aDiscerner is not in the bloom filter. 265 * 266 */ 267 Error SteeringDataCheckJoiner(const MeshCoP::JoinerDiscerner &aDiscerner) const; 268 269 /** 270 * This method gets the Service ID for the specified service. 271 * 272 * @param[in] aEnterpriseNumber Enterprise Number (IANA-assigned) for Service TLV 273 * @param[in] aServiceData The Service Data. 274 * @param[in] aServerStable The Stable flag value for Server TLV. 275 * @param[out] aServiceId A reference where to put the Service ID. 276 * 277 * @retval kErrorNone Successfully got the Service ID. 278 * @retval kErrorNotFound The specified service was not found. 279 * 280 */ 281 Error GetServiceId(uint32_t aEnterpriseNumber, 282 const ServiceData &aServiceData, 283 bool aServerStable, 284 uint8_t &aServiceId) const; 285 286 /** 287 * This methods gets the preferred NAT64 prefix from network data. 288 * 289 * The returned prefix is the highest preference external route entry in Network Data with NAT64 flag set. If there 290 * are multiple such entries the first one is returned. 291 * 292 * @param[out] aConfig A reference to an `ExternalRouteConfig` to return the prefix. 293 * 294 * @retval kErrorNone Found the NAT64 prefix and updated @p aConfig. 295 * @retval kErrorNotFound Could not find any NAT64 entry. 296 * 297 */ 298 Error GetPreferredNat64Prefix(ExternalRouteConfig &aConfig) const; 299 300 protected: 301 void SignalNetDataChanged(void); 302 303 uint8_t mStableVersion; 304 uint8_t mVersion; 305 306 private: 307 using FilterIndexes = MeshCoP::SteeringData::HashBitIndexes; 308 309 const PrefixTlv *FindNextMatchingPrefixTlv(const Ip6::Address &aAddress, const PrefixTlv *aPrevTlv) const; 310 311 void RemoveCommissioningData(void); 312 313 template <typename EntryType> int CompareRouteEntries(const EntryType &aFirst, const EntryType &aSecond) const; 314 int CompareRouteEntries(int8_t aFirstPreference, 315 uint16_t aFirstRloc, 316 int8_t aSecondPreference, 317 uint16_t aSecondRloc) const; 318 319 Error ExternalRouteLookup(uint8_t aDomainId, const Ip6::Address &aDestination, uint16_t &aRloc16) const; 320 Error DefaultRouteLookup(const PrefixTlv &aPrefix, uint16_t &aRloc16) const; 321 Error SteeringDataCheck(const FilterIndexes &aFilterIndexes) const; 322 void GetContextForMeshLocalPrefix(Lowpan::Context &aContext) const; 323 324 uint8_t mTlvBuffer[kMaxSize]; 325 uint8_t mMaxLength; 326 }; 327 328 /** 329 * @} 330 */ 331 332 } // namespace NetworkData 333 } // namespace ot 334 335 #if OPENTHREAD_MTD 336 namespace ot { 337 namespace NetworkData { 338 class Leader : public LeaderBase 339 { 340 public: 341 using LeaderBase::LeaderBase; 342 }; 343 } // namespace NetworkData 344 } // namespace ot 345 #elif OPENTHREAD_FTD 346 #include "network_data_leader_ftd.hpp" 347 #else 348 #error "Please define OPENTHREAD_MTD=1 or OPENTHREAD_FTD=1" 349 #endif 350 351 #endif // NETWORK_DATA_LEADER_HPP_ 352