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 generating and processing MeshCoP TLVs. 32 * 33 */ 34 35 #ifndef MESHCOP_TLVS_HPP_ 36 #define MESHCOP_TLVS_HPP_ 37 38 #include "openthread-core-config.h" 39 40 #include <openthread/commissioner.h> 41 #include <openthread/dataset.h> 42 #include <openthread/platform/radio.h> 43 44 #include "common/const_cast.hpp" 45 #include "common/encoding.hpp" 46 #include "common/message.hpp" 47 #include "common/num_utils.hpp" 48 #include "common/string.hpp" 49 #include "common/tlvs.hpp" 50 #include "mac/mac_types.hpp" 51 #include "meshcop/extended_panid.hpp" 52 #include "meshcop/network_name.hpp" 53 #include "meshcop/timestamp.hpp" 54 #include "net/ip6_address.hpp" 55 #include "radio/radio.hpp" 56 #include "thread/key_manager.hpp" 57 #include "thread/mle_tlvs.hpp" 58 #include "thread/mle_types.hpp" 59 60 namespace ot { 61 namespace MeshCoP { 62 63 /** 64 * Implements MeshCoP TLV generation and parsing. 65 * 66 */ 67 OT_TOOL_PACKED_BEGIN 68 class Tlv : public ot::Tlv 69 { 70 public: 71 /** 72 * MeshCoP TLV Types. 73 * 74 */ 75 enum Type : uint8_t 76 { 77 kChannel = OT_MESHCOP_TLV_CHANNEL, ///< Channel TLV 78 kPanId = OT_MESHCOP_TLV_PANID, ///< PAN ID TLV 79 kExtendedPanId = OT_MESHCOP_TLV_EXTPANID, ///< Extended PAN ID TLV 80 kNetworkName = OT_MESHCOP_TLV_NETWORKNAME, ///< Network Name TLV 81 kPskc = OT_MESHCOP_TLV_PSKC, ///< PSKc TLV 82 kNetworkKey = OT_MESHCOP_TLV_NETWORKKEY, ///< Network Network Key TLV 83 kNetworkKeySequence = OT_MESHCOP_TLV_NETWORK_KEY_SEQUENCE, ///< Network Key Sequence TLV 84 kMeshLocalPrefix = OT_MESHCOP_TLV_MESHLOCALPREFIX, ///< Mesh Local Prefix TLV 85 kSteeringData = OT_MESHCOP_TLV_STEERING_DATA, ///< Steering Data TLV 86 kBorderAgentLocator = OT_MESHCOP_TLV_BORDER_AGENT_RLOC, ///< Border Agent Locator TLV 87 kCommissionerId = OT_MESHCOP_TLV_COMMISSIONER_ID, ///< Commissioner ID TLV 88 kCommissionerSessionId = OT_MESHCOP_TLV_COMM_SESSION_ID, ///< Commissioner Session ID TLV 89 kSecurityPolicy = OT_MESHCOP_TLV_SECURITYPOLICY, ///< Security Policy TLV 90 kGet = OT_MESHCOP_TLV_GET, ///< Get TLV 91 kActiveTimestamp = OT_MESHCOP_TLV_ACTIVETIMESTAMP, ///< Active Timestamp TLV 92 kCommissionerUdpPort = OT_MESHCOP_TLV_COMMISSIONER_UDP_PORT, ///< Commissioner UDP Port TLV 93 kState = OT_MESHCOP_TLV_STATE, ///< State TLV 94 kJoinerDtlsEncapsulation = OT_MESHCOP_TLV_JOINER_DTLS, ///< Joiner DTLS Encapsulation TLV 95 kJoinerUdpPort = OT_MESHCOP_TLV_JOINER_UDP_PORT, ///< Joiner UDP Port TLV 96 kJoinerIid = OT_MESHCOP_TLV_JOINER_IID, ///< Joiner IID TLV 97 kJoinerRouterLocator = OT_MESHCOP_TLV_JOINER_RLOC, ///< Joiner Router Locator TLV 98 kJoinerRouterKek = OT_MESHCOP_TLV_JOINER_ROUTER_KEK, ///< Joiner Router KEK TLV 99 kProvisioningUrl = OT_MESHCOP_TLV_PROVISIONING_URL, ///< Provisioning URL TLV 100 kVendorName = OT_MESHCOP_TLV_VENDOR_NAME_TLV, ///< meshcop Vendor Name TLV 101 kVendorModel = OT_MESHCOP_TLV_VENDOR_MODEL_TLV, ///< meshcop Vendor Model TLV 102 kVendorSwVersion = OT_MESHCOP_TLV_VENDOR_SW_VERSION_TLV, ///< meshcop Vendor SW Version TLV 103 kVendorData = OT_MESHCOP_TLV_VENDOR_DATA_TLV, ///< meshcop Vendor Data TLV 104 kVendorStackVersion = OT_MESHCOP_TLV_VENDOR_STACK_VERSION_TLV, ///< meshcop Vendor Stack Version TLV 105 kUdpEncapsulation = OT_MESHCOP_TLV_UDP_ENCAPSULATION_TLV, ///< meshcop UDP encapsulation TLV 106 kIp6Address = OT_MESHCOP_TLV_IPV6_ADDRESS_TLV, ///< meshcop IPv6 address TLV 107 kPendingTimestamp = OT_MESHCOP_TLV_PENDINGTIMESTAMP, ///< Pending Timestamp TLV 108 kDelayTimer = OT_MESHCOP_TLV_DELAYTIMER, ///< Delay Timer TLV 109 kChannelMask = OT_MESHCOP_TLV_CHANNELMASK, ///< Channel Mask TLV 110 kCount = OT_MESHCOP_TLV_COUNT, ///< Count TLV 111 kPeriod = OT_MESHCOP_TLV_PERIOD, ///< Period TLV 112 kScanDuration = OT_MESHCOP_TLV_SCAN_DURATION, ///< Scan Duration TLV 113 kEnergyList = OT_MESHCOP_TLV_ENERGY_LIST, ///< Energy List TLV 114 kDiscoveryRequest = OT_MESHCOP_TLV_DISCOVERYREQUEST, ///< Discovery Request TLV 115 kDiscoveryResponse = OT_MESHCOP_TLV_DISCOVERYRESPONSE, ///< Discovery Response TLV 116 kJoinerAdvertisement = OT_MESHCOP_TLV_JOINERADVERTISEMENT, ///< Joiner Advertisement TLV 117 }; 118 119 /** 120 * Max length of Provisioning URL TLV. 121 * 122 */ 123 static constexpr uint8_t kMaxProvisioningUrlLength = OT_PROVISIONING_URL_MAX_SIZE; 124 125 static constexpr uint8_t kMaxCommissionerIdLength = 64; ///< Max length of Commissioner ID TLV. 126 static constexpr uint8_t kMaxVendorNameLength = 32; ///< Max length of Vendor Name TLV. 127 static constexpr uint8_t kMaxVendorModelLength = 32; ///< Max length of Vendor Model TLV. 128 static constexpr uint8_t kMaxVendorSwVersionLength = 16; ///< Max length of Vendor SW Version TLV. 129 static constexpr uint8_t kMaxVendorDataLength = 64; ///< Max length of Vendor Data TLV. 130 131 /** 132 * Returns the Type value. 133 * 134 * @returns The Type value. 135 * 136 */ GetType(void) const137 Type GetType(void) const { return static_cast<Type>(ot::Tlv::GetType()); } 138 139 /** 140 * Sets the Type value. 141 * 142 * @param[in] aType The Type value. 143 * 144 */ SetType(Type aType)145 void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); } 146 147 /** 148 * Returns a pointer to the next TLV. 149 * 150 * @returns A pointer to the next TLV. 151 * 152 */ GetNext(void)153 Tlv *GetNext(void) { return As<Tlv>(ot::Tlv::GetNext()); } 154 155 /** 156 * Returns a pointer to the next TLV. 157 * 158 * @returns A pointer to the next TLV. 159 * 160 */ GetNext(void) const161 const Tlv *GetNext(void) const { return As<Tlv>(ot::Tlv::GetNext()); } 162 163 /** 164 * Indicates whether a TLV appears to be well-formed. 165 * 166 * @param[in] aTlv A reference to the TLV. 167 * 168 * @returns TRUE if the TLV appears to be well-formed, FALSE otherwise. 169 * 170 */ 171 static bool IsValid(const Tlv &aTlv); 172 173 } OT_TOOL_PACKED_END; 174 175 /** 176 * Implements extended MeshCoP TLV generation and parsing. 177 * 178 */ 179 OT_TOOL_PACKED_BEGIN 180 class ExtendedTlv : public ot::ExtendedTlv 181 { 182 public: 183 /** 184 * Returns the Type value. 185 * 186 * @returns The Type value. 187 * 188 */ GetType(void) const189 MeshCoP::Tlv::Type GetType(void) const { return static_cast<MeshCoP::Tlv::Type>(ot::ExtendedTlv::GetType()); } 190 191 /** 192 * Sets the Type value. 193 * 194 * @param[in] aType The Type value. 195 * 196 */ SetType(MeshCoP::Tlv::Type aType)197 void SetType(MeshCoP::Tlv::Type aType) { ot::ExtendedTlv::SetType(static_cast<uint8_t>(aType)); } 198 } OT_TOOL_PACKED_END; 199 200 /** 201 * Defines Commissioner UDP Port TLV constants and types. 202 * 203 */ 204 typedef UintTlvInfo<Tlv::kCommissionerUdpPort, uint16_t> CommissionerUdpPortTlv; 205 206 /** 207 * Defines IPv6 Address TLV constants and types. 208 * 209 */ 210 typedef SimpleTlvInfo<Tlv::kIp6Address, Ip6::Address> Ip6AddressTlv; 211 212 /** 213 * Defines Joiner IID TLV constants and types. 214 * 215 */ 216 typedef SimpleTlvInfo<Tlv::kJoinerIid, Ip6::InterfaceIdentifier> JoinerIidTlv; 217 218 /** 219 * Defines Joiner Router Locator TLV constants and types. 220 * 221 */ 222 typedef UintTlvInfo<Tlv::kJoinerRouterLocator, uint16_t> JoinerRouterLocatorTlv; 223 224 /** 225 * Defines Joiner Router KEK TLV constants and types. 226 * 227 */ 228 typedef SimpleTlvInfo<Tlv::kJoinerRouterKek, Kek> JoinerRouterKekTlv; 229 230 /** 231 * Defines Count TLV constants and types. 232 * 233 */ 234 typedef UintTlvInfo<Tlv::kCount, uint8_t> CountTlv; 235 236 /** 237 * Defines Period TLV constants and types. 238 * 239 */ 240 typedef UintTlvInfo<Tlv::kPeriod, uint16_t> PeriodTlv; 241 242 /** 243 * Defines Scan Duration TLV constants and types. 244 * 245 */ 246 typedef UintTlvInfo<Tlv::kScanDuration, uint16_t> ScanDurationTlv; 247 248 /** 249 * Defines Commissioner ID TLV constants and types. 250 * 251 */ 252 typedef StringTlvInfo<Tlv::kCommissionerId, Tlv::kMaxCommissionerIdLength> CommissionerIdTlv; 253 254 /** 255 * Implements Channel TLV value format. 256 * 257 */ 258 typedef Mle::ChannelTlvValue ChannelTlvValue; 259 260 /** 261 * Defines Channel TLV constants and types. 262 * 263 */ 264 typedef SimpleTlvInfo<Tlv::kChannel, ChannelTlvValue> ChannelTlv; 265 266 /** 267 * Defines PAN ID TLV constants and types. 268 * 269 */ 270 typedef UintTlvInfo<Tlv::kPanId, uint16_t> PanIdTlv; 271 272 /** 273 * Defines Extended PAN ID TLV constants and types. 274 * 275 */ 276 typedef SimpleTlvInfo<Tlv::kExtendedPanId, ExtendedPanId> ExtendedPanIdTlv; 277 278 /** 279 * Implements Network Name TLV generation and parsing. 280 * 281 */ 282 OT_TOOL_PACKED_BEGIN 283 class NetworkNameTlv : public Tlv, public TlvInfo<Tlv::kNetworkName> 284 { 285 public: 286 /** 287 * Initializes the TLV. 288 * 289 */ Init(void)290 void Init(void) 291 { 292 SetType(kNetworkName); 293 SetLength(sizeof(*this) - sizeof(Tlv)); 294 } 295 296 /** 297 * Indicates whether or not the TLV appears to be well-formed. 298 * 299 * @retval TRUE If the TLV appears to be well-formed. 300 * @retval FALSE If the TLV does not appear to be well-formed. 301 * 302 */ 303 bool IsValid(void) const; 304 305 /** 306 * Gets the Network Name value. 307 * 308 * @returns The Network Name value (as `NameData`). 309 * 310 */ 311 NameData GetNetworkName(void) const; 312 313 /** 314 * Sets the Network Name value. 315 * 316 * @param[in] aNameData A Network Name value (as `NameData`). 317 * 318 */ 319 void SetNetworkName(const NameData &aNameData); 320 321 private: 322 char mNetworkName[NetworkName::kMaxSize]; 323 } OT_TOOL_PACKED_END; 324 325 /** 326 * Defines PSKc TLV constants and types. 327 * 328 */ 329 typedef SimpleTlvInfo<Tlv::kPskc, Pskc> PskcTlv; 330 331 /** 332 * Defines Network Key TLV constants and types. 333 * 334 */ 335 typedef SimpleTlvInfo<Tlv::kNetworkKey, NetworkKey> NetworkKeyTlv; 336 337 /** 338 * Defines Network Key Sequence TLV constants and types. 339 * 340 */ 341 typedef UintTlvInfo<Tlv::kNetworkKeySequence, uint32_t> NetworkKeySequenceTlv; 342 343 /** 344 * Defines Mesh Local Prefix TLV constants and types. 345 * 346 */ 347 typedef SimpleTlvInfo<Tlv::kMeshLocalPrefix, Ip6::NetworkPrefix> MeshLocalPrefixTlv; 348 349 class SteeringData; 350 351 /** 352 * Implements Steering Data TLV generation and parsing. 353 * 354 */ 355 OT_TOOL_PACKED_BEGIN 356 class SteeringDataTlv : public Tlv, public TlvInfo<Tlv::kSteeringData> 357 { 358 public: 359 /** 360 * Initializes the TLV. 361 * 362 */ Init(void)363 void Init(void) 364 { 365 SetType(kSteeringData); 366 SetLength(sizeof(*this) - sizeof(Tlv)); 367 Clear(); 368 } 369 370 /** 371 * Indicates whether or not the TLV appears to be well-formed. 372 * 373 * @retval TRUE If the TLV appears to be well-formed. 374 * @retval FALSE If the TLV does not appear to be well-formed. 375 * 376 */ IsValid(void) const377 bool IsValid(void) const { return GetLength() > 0; } 378 379 /** 380 * Returns the Steering Data length. 381 * 382 * @returns The Steering Data length. 383 * 384 */ GetSteeringDataLength(void) const385 uint8_t GetSteeringDataLength(void) const 386 { 387 return GetLength() <= sizeof(mSteeringData) ? GetLength() : sizeof(mSteeringData); 388 } 389 390 /** 391 * Sets all bits in the Bloom Filter to zero. 392 * 393 */ Clear(void)394 void Clear(void) { memset(mSteeringData, 0, GetSteeringDataLength()); } 395 396 /** 397 * Copies the Steering Data from the TLV into a given `SteeringData` variable. 398 * 399 * @param[out] aSteeringData A reference to a `SteeringData` to copy into. 400 * 401 */ 402 void CopyTo(SteeringData &aSteeringData) const; 403 404 private: 405 uint8_t mSteeringData[OT_STEERING_DATA_MAX_LENGTH]; 406 } OT_TOOL_PACKED_END; 407 408 /** 409 * Implements Border Agent Locator TLV generation and parsing. 410 * 411 */ 412 OT_TOOL_PACKED_BEGIN 413 class BorderAgentLocatorTlv : public Tlv, public UintTlvInfo<Tlv::kBorderAgentLocator, uint16_t> 414 { 415 public: 416 /** 417 * Initializes the TLV. 418 * 419 */ Init(void)420 void Init(void) 421 { 422 SetType(kBorderAgentLocator); 423 SetLength(sizeof(*this) - sizeof(Tlv)); 424 } 425 426 /** 427 * Indicates whether or not the TLV appears to be well-formed. 428 * 429 * @retval TRUE If the TLV appears to be well-formed. 430 * @retval FALSE If the TLV does not appear to be well-formed. 431 * 432 */ IsValid(void) const433 bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); } 434 435 /** 436 * Returns the Border Agent Locator value. 437 * 438 * @returns The Border Agent Locator value. 439 * 440 */ GetBorderAgentLocator(void) const441 uint16_t GetBorderAgentLocator(void) const { return BigEndian::HostSwap16(mLocator); } 442 443 /** 444 * Sets the Border Agent Locator value. 445 * 446 * @param[in] aLocator The Border Agent Locator value. 447 * 448 */ SetBorderAgentLocator(uint16_t aLocator)449 void SetBorderAgentLocator(uint16_t aLocator) { mLocator = BigEndian::HostSwap16(aLocator); } 450 451 private: 452 uint16_t mLocator; 453 } OT_TOOL_PACKED_END; 454 455 /** 456 * Implements Commissioner Session ID TLV generation and parsing. 457 * 458 */ 459 OT_TOOL_PACKED_BEGIN 460 class CommissionerSessionIdTlv : public Tlv, public UintTlvInfo<Tlv::kCommissionerSessionId, uint16_t> 461 { 462 public: 463 /** 464 * Initializes the TLV. 465 * 466 */ Init(void)467 void Init(void) 468 { 469 SetType(kCommissionerSessionId); 470 SetLength(sizeof(*this) - sizeof(Tlv)); 471 } 472 473 /** 474 * Indicates whether or not the TLV appears to be well-formed. 475 * 476 * @retval TRUE If the TLV appears to be well-formed. 477 * @retval FALSE If the TLV does not appear to be well-formed. 478 * 479 */ IsValid(void) const480 bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); } 481 482 /** 483 * Returns the Commissioner Session ID value. 484 * 485 * @returns The Commissioner Session ID value. 486 * 487 */ GetCommissionerSessionId(void) const488 uint16_t GetCommissionerSessionId(void) const { return BigEndian::HostSwap16(mSessionId); } 489 490 /** 491 * Sets the Commissioner Session ID value. 492 * 493 * @param[in] aSessionId The Commissioner Session ID value. 494 * 495 */ SetCommissionerSessionId(uint16_t aSessionId)496 void SetCommissionerSessionId(uint16_t aSessionId) { mSessionId = BigEndian::HostSwap16(aSessionId); } 497 498 private: 499 uint16_t mSessionId; 500 } OT_TOOL_PACKED_END; 501 502 /** 503 * Implements Security Policy TLV generation and parsing. 504 * 505 */ 506 OT_TOOL_PACKED_BEGIN 507 class SecurityPolicyTlv : public Tlv, public TlvInfo<Tlv::kSecurityPolicy> 508 { 509 public: 510 /** 511 * Initializes the TLV. 512 * 513 */ Init(void)514 void Init(void) 515 { 516 SetType(kSecurityPolicy); 517 SetLength(sizeof(*this) - sizeof(Tlv)); 518 } 519 520 /** 521 * Indicates whether or not the TLV appears to be well-formed. 522 * 523 * @retval TRUE If the TLV appears to be well-formed. 524 * @retval FALSE If the TLV does not appear to be well-formed. 525 * 526 */ 527 bool IsValid(void) const; 528 529 /** 530 * Returns the Security Policy. 531 * 532 * @returns The Security Policy. 533 * 534 */ 535 SecurityPolicy GetSecurityPolicy(void) const; 536 537 /** 538 * Sets the Security Policy. 539 * 540 * @param[in] aSecurityPolicy The Security Policy which will be set. 541 * 542 */ 543 void SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy); 544 545 private: 546 static constexpr uint8_t kThread11FlagsLength = 1; // The Thread 1.1 Security Policy Flags length. 547 static constexpr uint8_t kThread12FlagsLength = 2; // The Thread 1.2 Security Policy Flags length. 548 SetRotationTime(uint16_t aRotationTime)549 void SetRotationTime(uint16_t aRotationTime) { mRotationTime = BigEndian::HostSwap16(aRotationTime); } GetRotationTime(void) const550 uint16_t GetRotationTime(void) const { return BigEndian::HostSwap16(mRotationTime); } GetFlagsLength(void) const551 uint8_t GetFlagsLength(void) const { return GetLength() - sizeof(mRotationTime); } 552 553 uint16_t mRotationTime; 554 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 555 uint8_t mFlags[kThread12FlagsLength]; 556 #else 557 uint8_t mFlags[kThread11FlagsLength]; 558 #endif 559 } OT_TOOL_PACKED_END; 560 561 /** 562 * Defines Active Timestamp TLV constants and types. 563 * 564 */ 565 typedef SimpleTlvInfo<Tlv::kActiveTimestamp, Timestamp> ActiveTimestampTlv; 566 567 /** 568 * Implements State TLV generation and parsing. 569 * 570 */ 571 class StateTlv : public UintTlvInfo<Tlv::kState, uint8_t> 572 { 573 public: 574 StateTlv(void) = delete; 575 576 /** 577 * State values. 578 * 579 */ 580 enum State : uint8_t 581 { 582 kReject = 0xff, ///< Reject (-1) 583 kPending = 0, ///< Pending 584 kAccept = 1, ///< Accept 585 }; 586 587 /** 588 * Converts a `State` to a string. 589 * 590 * @param[in] aState An item state. 591 * 592 * @returns A string representation of @p aState. 593 * 594 */ 595 static const char *StateToString(State aState); 596 }; 597 598 /** 599 * Defines Joiner UDP Port TLV constants and types. 600 * 601 */ 602 typedef UintTlvInfo<Tlv::kJoinerUdpPort, uint16_t> JoinerUdpPortTlv; 603 604 /** 605 * Defines Pending Timestamp TLV constants and types. 606 * 607 */ 608 typedef SimpleTlvInfo<Tlv::kPendingTimestamp, Timestamp> PendingTimestampTlv; 609 610 /** 611 * Defines Delay Timer TLV constants and types. 612 * 613 */ 614 typedef UintTlvInfo<Tlv::kDelayTimer, uint32_t> DelayTimerTlv; 615 616 /** 617 * Implements Channel Mask TLV generation and parsing. 618 * 619 */ 620 OT_TOOL_PACKED_BEGIN 621 class ChannelMaskTlv : public Tlv, public TlvInfo<Tlv::kChannelMask> 622 { 623 static constexpr uint8_t kEntryHeaderSize = 2; // Two bytes: mChannelPage and mMaskLength 624 static constexpr uint8_t kEntrySize = kEntryHeaderSize + sizeof(uint32_t); 625 626 public: 627 /** 628 * Represents Channel Mask TLV value to append. 629 * 630 */ 631 struct Value 632 { 633 static constexpr uint16_t kMaxLength = (kEntrySize * Radio::kNumChannelPages); ///< Max value length. 634 635 uint8_t mData[kMaxLength]; ///< Array to store TLV value (encoded as one or more Channel Mask TLV Entry) 636 uint8_t mLength; ///< Value length in bytes. 637 }; 638 639 ChannelMaskTlv(void) = delete; 640 641 /** 642 * Parses the Channel Mask TLV value and validates that all the included entries are well-formed. 643 * 644 * @returns TRUE if the TLV is well-formed, FALSE otherwise. 645 * 646 */ 647 bool IsValid(void) const; 648 649 /** 650 * Parses and retrieves the combined channel mask for all supported channel pages from entries in the TLV. 651 * 652 * @param[out] aChannelMask A reference to return the channel mask. 653 * 654 * @retval kErrorNone Successfully parsed the TLV value, @p aChannelMask is updated. 655 * @retval kErrorParse TLV value is not well-formed. 656 * 657 */ 658 Error ReadChannelMask(uint32_t &aChannelMask) const; 659 660 /** 661 * Searches within a given message for Channel Mask TLV, parses and validates the TLV value and returns the 662 * combined channel mask for all supported channel pages included in the TLV. 663 * 664 * @param[in] aMessage The message to search in. 665 * @param[out] aChannelMask A reference to return the channel mask. 666 * 667 * @retval kErrorNone Found the TLV, successfully parsed its value, @p aChannelMask is updated. 668 * @retval kErrorNotFound No Channel Mask TLV found in the @p aMessage. 669 * @retval kErrorParse Found the TLV, but failed to parse it. 670 * 671 */ 672 static Error FindIn(const Message &aMessage, uint32_t &aChannelMask); 673 674 /** 675 * Prepares Channel Mask TLV value for appending/writing. 676 * 677 * @param[out] aValue A reference to `Value` structure to populate. 678 * @param[in] aChannelMask The combined channel mask for all supported channel pages. 679 * 680 */ 681 static void PrepareValue(Value &aValue, uint32_t aChannelMask); 682 683 /** 684 * Prepares a Channel Mask TLV value and appends the TLV to a given message. 685 * 686 * @param[in] aMessage The message to append to. 687 * @param[in] aChannelMask The combined channel mask for all supported channel pages. 688 * 689 * @retval kErrorNone Successfully prepared the Channel Mask TLV and appended it to @p aMessage. 690 * @retval kErrorNoBufs Insufficient available buffers to grow the message. 691 * 692 */ 693 static Error AppendTo(Message &aMessage, uint32_t aChannelMask); 694 695 private: 696 static constexpr uint8_t kMaskLength = sizeof(uint32_t); 697 698 OT_TOOL_PACKED_BEGIN 699 class Entry 700 { 701 public: GetChannelPage(void) const702 uint8_t GetChannelPage(void) const { return mChannelPage; } SetChannelPage(uint8_t aChannelPage)703 void SetChannelPage(uint8_t aChannelPage) { mChannelPage = aChannelPage; } GetMaskLength(void) const704 uint8_t GetMaskLength(void) const { return mMaskLength; } SetMaskLength(uint8_t aMaskLength)705 void SetMaskLength(uint8_t aMaskLength) { mMaskLength = aMaskLength; } GetMask(void) const706 uint32_t GetMask(void) const { return Reverse32(BigEndian::HostSwap32(mMask)); } SetMask(uint32_t aMask)707 void SetMask(uint32_t aMask) { mMask = BigEndian::HostSwap32(Reverse32(aMask)); } 708 709 private: 710 uint8_t mChannelPage; 711 uint8_t mMaskLength; 712 uint32_t mMask; 713 } OT_TOOL_PACKED_END; 714 715 struct EntriesData : public Clearable<EntriesData> 716 { 717 // Represents received Channel Mask TLV Entries data which 718 // is either contained in `mData` buffer, or in `mMessage` 719 // at `mOffset`. 720 721 Error Parse(uint32_t &aChannelMask); 722 723 const uint8_t *mData; 724 const Message *mMessage; 725 uint16_t mOffset; 726 uint16_t mLength; 727 }; 728 729 uint8_t mEntriesStart; 730 } OT_TOOL_PACKED_BEGIN; 731 732 /** 733 * Implements Energy List TLV generation and parsing. 734 * 735 */ 736 OT_TOOL_PACKED_BEGIN 737 class EnergyListTlv : public Tlv, public TlvInfo<Tlv::kEnergyList> 738 { 739 public: 740 /** 741 * Initializes the TLV. 742 * 743 */ Init(void)744 void Init(void) 745 { 746 SetType(kEnergyList); 747 SetLength(sizeof(*this) - sizeof(Tlv)); 748 } 749 750 /** 751 * Indicates whether or not the TLV appears to be well-formed. 752 * 753 * @retval TRUE If the TLV appears to be well-formed. 754 * @retval FALSE If the TLV does not appear to be well-formed. 755 * 756 */ IsValid(void) const757 bool IsValid(void) const { return true; } 758 759 /** 760 * Returns a pointer to the start of energy measurement list. 761 * 762 * @returns A pointer to the start start of energy energy measurement list. 763 * 764 */ GetEnergyList(void) const765 const uint8_t *GetEnergyList(void) const { return mEnergyList; } 766 767 /** 768 * Returns the length of energy measurement list. 769 * 770 * @returns The length of energy measurement list. 771 * 772 */ GetEnergyListLength(void) const773 uint8_t GetEnergyListLength(void) const { return Min(kMaxListLength, GetLength()); } 774 775 private: 776 static constexpr uint8_t kMaxListLength = OPENTHREAD_CONFIG_TMF_ENERGY_SCAN_MAX_RESULTS; 777 778 uint8_t mEnergyList[kMaxListLength]; 779 } OT_TOOL_PACKED_END; 780 781 /** 782 * Defines Provisioning TLV constants and types. 783 * 784 */ 785 typedef StringTlvInfo<Tlv::kProvisioningUrl, Tlv::kMaxProvisioningUrlLength> ProvisioningUrlTlv; 786 787 /** 788 * Defines Vendor Name TLV constants and types. 789 * 790 */ 791 typedef StringTlvInfo<Tlv::kVendorName, Tlv::kMaxVendorNameLength> VendorNameTlv; 792 793 /** 794 * Defines Vendor Model TLV constants and types. 795 * 796 */ 797 typedef StringTlvInfo<Tlv::kVendorModel, Tlv::kMaxVendorModelLength> VendorModelTlv; 798 799 /** 800 * Defines Vendor SW Version TLV constants and types. 801 * 802 */ 803 typedef StringTlvInfo<Tlv::kVendorSwVersion, Tlv::kMaxVendorSwVersionLength> VendorSwVersionTlv; 804 805 /** 806 * Defines Vendor Data TLV constants and types. 807 * 808 */ 809 typedef StringTlvInfo<Tlv::kVendorData, Tlv::kMaxVendorDataLength> VendorDataTlv; 810 811 /** 812 * Implements Vendor Stack Version TLV generation and parsing. 813 * 814 */ 815 OT_TOOL_PACKED_BEGIN 816 class VendorStackVersionTlv : public Tlv, public TlvInfo<Tlv::kVendorStackVersion> 817 { 818 public: 819 /** 820 * Default constructor. 821 * 822 */ VendorStackVersionTlv(void)823 VendorStackVersionTlv(void) 824 : mBuildRevision(0) 825 , mMinorMajor(0) 826 { 827 } 828 829 /** 830 * Initializes the TLV. 831 * 832 */ Init(void)833 void Init(void) 834 { 835 SetType(kVendorStackVersion); 836 SetLength(sizeof(*this) - sizeof(Tlv)); 837 } 838 839 /** 840 * Indicates whether or not the TLV appears to be well-formed. 841 * 842 * @retval TRUE If the TLV appears to be well-formed. 843 * @retval FALSE If the TLV does not appear to be well-formed. 844 * 845 */ IsValid(void) const846 bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); } 847 848 /** 849 * Returns the Stack Vendor OUI value. 850 * 851 * @returns The Vendor Stack Vendor OUI value. 852 * 853 */ GetOui(void) const854 uint32_t GetOui(void) const { return BigEndian::ReadUint24(mOui); } 855 856 /** 857 * Returns the Stack Vendor OUI value. 858 * 859 * @param[in] aOui The Vendor Stack Vendor OUI value. 860 * 861 */ SetOui(uint32_t aOui)862 void SetOui(uint32_t aOui) { BigEndian::WriteUint24(aOui, mOui); } 863 864 /** 865 * Returns the Build value. 866 * 867 * @returns The Build value. 868 * 869 */ GetBuild(void) const870 uint16_t GetBuild(void) const { return (BigEndian::HostSwap16(mBuildRevision) & kBuildMask) >> kBuildOffset; } 871 872 /** 873 * Sets the Build value. 874 * 875 * @param[in] aBuild The Build value. 876 * 877 */ SetBuild(uint16_t aBuild)878 void SetBuild(uint16_t aBuild) 879 { 880 mBuildRevision = BigEndian::HostSwap16((BigEndian::HostSwap16(mBuildRevision) & ~kBuildMask) | 881 ((aBuild << kBuildOffset) & kBuildMask)); 882 } 883 884 /** 885 * Returns the Revision value. 886 * 887 * @returns The Revision value. 888 * 889 */ GetRevision(void) const890 uint8_t GetRevision(void) const { return (BigEndian::HostSwap16(mBuildRevision) & kRevMask) >> kRevOffset; } 891 892 /** 893 * Sets the Revision value. 894 * 895 * @param[in] aRevision The Revision value. 896 * 897 */ SetRevision(uint8_t aRevision)898 void SetRevision(uint8_t aRevision) 899 { 900 mBuildRevision = BigEndian::HostSwap16((BigEndian::HostSwap16(mBuildRevision) & ~kRevMask) | 901 ((aRevision << kRevOffset) & kRevMask)); 902 } 903 904 /** 905 * Returns the Minor value. 906 * 907 * @returns The Minor value. 908 * 909 */ GetMinor(void) const910 uint8_t GetMinor(void) const { return (mMinorMajor & kMinorMask) >> kMinorOffset; } 911 912 /** 913 * Sets the Minor value. 914 * 915 * @param[in] aMinor The Minor value. 916 * 917 */ SetMinor(uint8_t aMinor)918 void SetMinor(uint8_t aMinor) 919 { 920 mMinorMajor = (mMinorMajor & ~kMinorMask) | ((aMinor << kMinorOffset) & kMinorMask); 921 } 922 923 /** 924 * Returns the Major value. 925 * 926 * @returns The Major value. 927 * 928 */ GetMajor(void) const929 uint8_t GetMajor(void) const { return (mMinorMajor & kMajorMask) >> kMajorOffset; } 930 931 /** 932 * Sets the Major value. 933 * 934 * @param[in] aMajor The Major value. 935 * 936 */ SetMajor(uint8_t aMajor)937 void SetMajor(uint8_t aMajor) 938 { 939 mMinorMajor = (mMinorMajor & ~kMajorMask) | ((aMajor << kMajorOffset) & kMajorMask); 940 } 941 942 private: 943 // For `mBuildRevision` 944 static constexpr uint8_t kBuildOffset = 4; 945 static constexpr uint16_t kBuildMask = 0xfff << kBuildOffset; 946 static constexpr uint8_t kRevOffset = 0; 947 static constexpr uint16_t kRevMask = 0xf << kBuildOffset; 948 949 // For `mMinorMajor` 950 static constexpr uint8_t kMinorOffset = 4; 951 static constexpr uint8_t kMinorMask = 0xf << kMinorOffset; 952 static constexpr uint8_t kMajorOffset = 0; 953 static constexpr uint8_t kMajorMask = 0xf << kMajorOffset; 954 955 uint8_t mOui[3]; 956 uint16_t mBuildRevision; 957 uint8_t mMinorMajor; 958 } OT_TOOL_PACKED_END; 959 960 /** 961 * Defines UDP Encapsulation TLV types and constants. 962 * 963 */ 964 typedef TlvInfo<MeshCoP::Tlv::kUdpEncapsulation> UdpEncapsulationTlv; 965 966 /** 967 * Represents UDP Encapsulation TLV value header (source and destination ports). 968 * 969 */ 970 OT_TOOL_PACKED_BEGIN 971 class UdpEncapsulationTlvHeader 972 { 973 public: 974 /** 975 * Returns the source port. 976 * 977 * @returns The source port. 978 * 979 */ GetSourcePort(void) const980 uint16_t GetSourcePort(void) const { return BigEndian::HostSwap16(mSourcePort); } 981 982 /** 983 * Updates the source port. 984 * 985 * @param[in] aSourcePort The source port. 986 * 987 */ SetSourcePort(uint16_t aSourcePort)988 void SetSourcePort(uint16_t aSourcePort) { mSourcePort = BigEndian::HostSwap16(aSourcePort); } 989 990 /** 991 * Returns the destination port. 992 * 993 * @returns The destination port. 994 * 995 */ GetDestinationPort(void) const996 uint16_t GetDestinationPort(void) const { return BigEndian::HostSwap16(mDestinationPort); } 997 998 /** 999 * Updates the destination port. 1000 * 1001 * @param[in] aDestinationPort The destination port. 1002 * 1003 */ SetDestinationPort(uint16_t aDestinationPort)1004 void SetDestinationPort(uint16_t aDestinationPort) { mDestinationPort = BigEndian::HostSwap16(aDestinationPort); } 1005 1006 private: 1007 uint16_t mSourcePort; 1008 uint16_t mDestinationPort; 1009 // Followed by the UDP Payload. 1010 } OT_TOOL_PACKED_END; 1011 1012 /** 1013 * Implements Discovery Request TLV generation and parsing. 1014 * 1015 */ 1016 OT_TOOL_PACKED_BEGIN 1017 class DiscoveryRequestTlv : public Tlv, public TlvInfo<Tlv::kDiscoveryRequest> 1018 { 1019 public: 1020 /** 1021 * Initializes the TLV. 1022 * 1023 */ Init(void)1024 void Init(void) 1025 { 1026 SetType(kDiscoveryRequest); 1027 SetLength(sizeof(*this) - sizeof(Tlv)); 1028 mFlags = 0; 1029 mReserved = 0; 1030 } 1031 1032 /** 1033 * Indicates whether or not the TLV appears to be well-formed. 1034 * 1035 * @retval TRUE If the TLV appears to be well-formed. 1036 * @retval FALSE If the TLV does not appear to be well-formed. 1037 * 1038 */ IsValid(void) const1039 bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); } 1040 1041 /** 1042 * Returns the Version value. 1043 * 1044 * @returns The Version value. 1045 * 1046 */ GetVersion(void) const1047 uint8_t GetVersion(void) const { return mFlags >> kVersionOffset; } 1048 1049 /** 1050 * Sets the Version value. 1051 * 1052 * @param[in] aVersion The Version value. 1053 * 1054 */ SetVersion(uint8_t aVersion)1055 void SetVersion(uint8_t aVersion) 1056 { 1057 mFlags = (mFlags & ~kVersionMask) | ((aVersion << kVersionOffset) & kVersionMask); 1058 } 1059 1060 /** 1061 * Indicates whether or not the Joiner flag is set. 1062 * 1063 * @retval TRUE If the Joiner flag is set. 1064 * @retval FALSE If the Joiner flag is not set. 1065 * 1066 */ IsJoiner(void) const1067 bool IsJoiner(void) const { return (mFlags & kJoinerMask) != 0; } 1068 1069 /** 1070 * Sets the Joiner flag. 1071 * 1072 * @param[in] aJoiner TRUE if set, FALSE otherwise. 1073 * 1074 */ SetJoiner(bool aJoiner)1075 void SetJoiner(bool aJoiner) 1076 { 1077 if (aJoiner) 1078 { 1079 mFlags |= kJoinerMask; 1080 } 1081 else 1082 { 1083 mFlags &= ~kJoinerMask; 1084 } 1085 } 1086 1087 private: 1088 static constexpr uint8_t kVersionOffset = 4; 1089 static constexpr uint8_t kVersionMask = 0xf << kVersionOffset; 1090 static constexpr uint8_t kJoinerOffset = 3; 1091 static constexpr uint8_t kJoinerMask = 1 << kJoinerOffset; 1092 1093 uint8_t mFlags; 1094 uint8_t mReserved; 1095 } OT_TOOL_PACKED_END; 1096 1097 /** 1098 * Implements Discovery Response TLV generation and parsing. 1099 * 1100 */ 1101 OT_TOOL_PACKED_BEGIN 1102 class DiscoveryResponseTlv : public Tlv, public TlvInfo<Tlv::kDiscoveryResponse> 1103 { 1104 public: 1105 /** 1106 * Initializes the TLV. 1107 * 1108 */ Init(void)1109 void Init(void) 1110 { 1111 SetType(kDiscoveryResponse); 1112 SetLength(sizeof(*this) - sizeof(Tlv)); 1113 mFlags = 0; 1114 mReserved = 0; 1115 } 1116 1117 /** 1118 * Indicates whether or not the TLV appears to be well-formed. 1119 * 1120 * @retval TRUE If the TLV appears to be well-formed. 1121 * @retval FALSE If the TLV does not appear to be well-formed. 1122 * 1123 */ IsValid(void) const1124 bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); } 1125 1126 /** 1127 * Returns the Version value. 1128 * 1129 * @returns The Version value. 1130 * 1131 */ GetVersion(void) const1132 uint8_t GetVersion(void) const { return mFlags >> kVersionOffset; } 1133 1134 /** 1135 * Sets the Version value. 1136 * 1137 * @param[in] aVersion The Version value. 1138 * 1139 */ SetVersion(uint8_t aVersion)1140 void SetVersion(uint8_t aVersion) 1141 { 1142 mFlags = (mFlags & ~kVersionMask) | ((aVersion << kVersionOffset) & kVersionMask); 1143 } 1144 1145 /** 1146 * Indicates whether or not the Native Commissioner flag is set. 1147 * 1148 * @retval TRUE If the Native Commissioner flag is set. 1149 * @retval FALSE If the Native Commissioner flag is not set. 1150 * 1151 */ IsNativeCommissioner(void) const1152 bool IsNativeCommissioner(void) const { return (mFlags & kNativeMask) != 0; } 1153 1154 /** 1155 * Sets the Native Commissioner flag. 1156 * 1157 * @param[in] aNativeCommissioner TRUE if set, FALSE otherwise. 1158 * 1159 */ SetNativeCommissioner(bool aNativeCommissioner)1160 void SetNativeCommissioner(bool aNativeCommissioner) 1161 { 1162 if (aNativeCommissioner) 1163 { 1164 mFlags |= kNativeMask; 1165 } 1166 else 1167 { 1168 mFlags &= ~kNativeMask; 1169 } 1170 } 1171 1172 /** 1173 * Indicates whether or not the Commercial Commissioning Mode flag is set. 1174 * 1175 * @retval TRUE If the Commercial Commissioning Mode flag is set. 1176 * @retval FALSE If the Commercial Commissioning Mode flag is not set. 1177 * 1178 */ IsCommercialCommissioningMode(void) const1179 bool IsCommercialCommissioningMode(void) const { return (mFlags & kCcmMask) != 0; } 1180 1181 /** 1182 * Sets the Commercial Commissioning Mode flag. 1183 * 1184 * @param[in] aCcm TRUE if set, FALSE otherwise. 1185 * 1186 */ SetCommercialCommissioningMode(bool aCcm)1187 void SetCommercialCommissioningMode(bool aCcm) 1188 { 1189 if (aCcm) 1190 { 1191 mFlags |= kCcmMask; 1192 } 1193 else 1194 { 1195 mFlags &= ~kCcmMask; 1196 } 1197 } 1198 1199 private: 1200 static constexpr uint8_t kVersionOffset = 4; 1201 static constexpr uint8_t kVersionMask = 0xf << kVersionOffset; 1202 static constexpr uint8_t kNativeOffset = 3; 1203 static constexpr uint8_t kNativeMask = 1 << kNativeOffset; 1204 static constexpr uint8_t kCcmOffset = 2; 1205 static constexpr uint8_t kCcmMask = 1 << kCcmOffset; 1206 1207 uint8_t mFlags; 1208 uint8_t mReserved; 1209 } OT_TOOL_PACKED_END; 1210 1211 /** 1212 * Implements Joiner Advertisement TLV generation and parsing. 1213 * 1214 */ 1215 OT_TOOL_PACKED_BEGIN 1216 class JoinerAdvertisementTlv : public Tlv, public TlvInfo<Tlv::kJoinerAdvertisement> 1217 { 1218 public: 1219 static constexpr uint8_t kAdvDataMaxLength = OT_JOINER_ADVDATA_MAX_LENGTH; ///< The Max Length of AdvData 1220 1221 /** 1222 * Initializes the TLV. 1223 * 1224 */ Init(void)1225 void Init(void) 1226 { 1227 SetType(kJoinerAdvertisement); 1228 SetLength(sizeof(*this) - sizeof(Tlv)); 1229 } 1230 1231 /** 1232 * Indicates whether or not the TLV appears to be well-formed. 1233 * 1234 * @retval TRUE If the TLV appears to be well-formed. 1235 * @retval FALSE If the TLV does not appear to be well-formed. 1236 * 1237 */ IsValid(void) const1238 bool IsValid(void) const { return GetLength() >= sizeof(mOui) && GetLength() <= sizeof(mOui) + sizeof(mAdvData); } 1239 1240 /** 1241 * Returns the Vendor OUI value. 1242 * 1243 * @returns The Vendor OUI value. 1244 * 1245 */ GetOui(void) const1246 uint32_t GetOui(void) const { return BigEndian::ReadUint24(mOui); } 1247 1248 /** 1249 * Sets the Vendor OUI value. 1250 * 1251 * @param[in] aOui The Vendor OUI value. 1252 * 1253 */ SetOui(uint32_t aOui)1254 void SetOui(uint32_t aOui) { return BigEndian::WriteUint24(aOui, mOui); } 1255 1256 /** 1257 * Returns the Adv Data length. 1258 * 1259 * @returns The AdvData length. 1260 * 1261 */ GetAdvDataLength(void) const1262 uint8_t GetAdvDataLength(void) const { return GetLength() - sizeof(mOui); } 1263 1264 /** 1265 * Returns the Adv Data value. 1266 * 1267 * @returns A pointer to the Adv Data value. 1268 * 1269 */ GetAdvData(void) const1270 const uint8_t *GetAdvData(void) const { return mAdvData; } 1271 1272 /** 1273 * Sets the Adv Data value. 1274 * 1275 * @param[in] aAdvData A pointer to the AdvData value. 1276 * @param[in] aAdvDataLength The length of AdvData in bytes. 1277 * 1278 */ SetAdvData(const uint8_t * aAdvData,uint8_t aAdvDataLength)1279 void SetAdvData(const uint8_t *aAdvData, uint8_t aAdvDataLength) 1280 { 1281 OT_ASSERT((aAdvData != nullptr) && (aAdvDataLength > 0) && (aAdvDataLength <= kAdvDataMaxLength)); 1282 1283 SetLength(aAdvDataLength + sizeof(mOui)); 1284 memcpy(mAdvData, aAdvData, aAdvDataLength); 1285 } 1286 1287 private: 1288 uint8_t mOui[3]; 1289 uint8_t mAdvData[kAdvDataMaxLength]; 1290 } OT_TOOL_PACKED_END; 1291 1292 } // namespace MeshCoP 1293 1294 } // namespace ot 1295 1296 #endif // MESHCOP_TLVS_HPP_ 1297