Matter SDK Coverage Report
Current view: top level - lib/support - ThreadOperationalDataset.cpp (source / functions) Coverage Total Hit
Test: SHA:da00cfb13e586707ec8d44ae49325a696d4a8855 Lines: 89.1 % 256 228
Test Date: 2025-08-16 07:11:35 Functions: 88.9 % 54 48

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2021 Project CHIP Authors
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : 
      18              : #include <lib/support/ThreadOperationalDataset.h>
      19              : 
      20              : #include <lib/core/CHIPEncoding.h>
      21              : 
      22              : #include <cassert>
      23              : #include <cstring>
      24              : 
      25              : namespace chip {
      26              : namespace Thread {
      27              : 
      28              : /**
      29              :  * The Thread specification defines two TLV element formats: a "base" format and an "extended" format.
      30              :  * The base format is used for TLV elements with a length of 0-254 bytes and is laid out as follows:
      31              :  *
      32              :  * +---------+---------+-------------------------+
      33              :  * | uint8_t | uint8_t | network byte order data |
      34              :  * | 1 byte  | 1 byte  | n byte (0 <= n < 255)   |
      35              :  * +---------+---------+-------------------------+
      36              :  * |  Type   | Length  | Value                   |
      37              :  * +---------+---------+-------------------------+
      38              :  *
      39              :  * A length values of 0xff (255) is an "escape" value and indicates that the element uses the "extended"
      40              :  * format, where a two-byte length field follows the 0xff escape byte.
      41              :  *
      42              :  * Only the base format is allowed in Thread Operational Datasets, so only this format is supported here.
      43              :  */
      44              : class ThreadTLV final
      45              : {
      46              : public:
      47              :     static constexpr uint8_t kLengthEscape = 0xff;
      48              : 
      49              :     enum : uint8_t
      50              :     {
      51              :         kChannel         = 0,
      52              :         kPanId           = 1,
      53              :         kExtendedPanId   = 2,
      54              :         kNetworkName     = 3,
      55              :         kPSKc            = 4,
      56              :         kMasterKey       = 5,
      57              :         kMeshLocalPrefix = 7,
      58              :         kSecurityPolicy  = 12,
      59              :         kActiveTimestamp = 14,
      60              :         kDelayTimer      = 52,
      61              :         kChannelMask     = 53,
      62              :     };
      63              : 
      64           34 :     size_t GetSize() const
      65              :     {
      66              :         static_assert(sizeof(*this) == 2, "ThreadTLV header should be 2 bytes (type, length)");
      67           34 :         return sizeof(*this) + GetLength();
      68              :     }
      69              : 
      70          279 :     uint8_t GetType() const { return mType; }
      71              : 
      72           27 :     void SetType(uint8_t aType) { mType = aType; }
      73              : 
      74          501 :     uint8_t GetLength() const { return mLength; }
      75              : 
      76           27 :     void SetLength(size_t aLength)
      77              :     {
      78           27 :         assert(aLength < kLengthEscape);
      79           27 :         mLength = static_cast<uint8_t>(aLength);
      80           27 :     }
      81              : 
      82          349 :     const uint8_t * GetValue() const
      83              :     {
      84          349 :         assert(mLength != kLengthEscape);
      85          349 :         return reinterpret_cast<const uint8_t *>(this) + sizeof(*this);
      86              :     }
      87              : 
      88           35 :     uint8_t * GetValue() { return const_cast<uint8_t *>(const_cast<const ThreadTLV *>(this)->GetValue()); }
      89              : 
      90            6 :     ByteSpan GetValueAsSpan() const { return ByteSpan(GetValue(), GetLength()); }
      91              : 
      92            6 :     void Get64(uint64_t & aValue) const
      93              :     {
      94            6 :         assert(GetLength() == sizeof(aValue));
      95            6 :         aValue = Encoding::BigEndian::Get64(GetValue());
      96            6 :     }
      97              : 
      98            2 :     void Get32(uint32_t & aValue) const
      99              :     {
     100            2 :         assert(GetLength() == sizeof(aValue));
     101            2 :         aValue = Encoding::BigEndian::Get32(GetValue());
     102            2 :     }
     103              : 
     104            5 :     void Get16(uint16_t & aValue) const
     105              :     {
     106            5 :         assert(GetLength() == sizeof(aValue));
     107            5 :         aValue = Encoding::BigEndian::Get16(GetValue());
     108            5 :     }
     109              : 
     110            3 :     void Set64(uint64_t aValue)
     111              :     {
     112            3 :         assert(GetLength() == sizeof(aValue));
     113            3 :         Encoding::BigEndian::Put64(GetValue(), aValue);
     114            3 :     }
     115              : 
     116            0 :     void Set32(uint32_t aValue)
     117              :     {
     118            0 :         assert(GetLength() == sizeof(aValue));
     119            0 :         Encoding::BigEndian::Put32(GetValue(), aValue);
     120            0 :     }
     121              : 
     122            4 :     void Set16(uint16_t aValue)
     123              :     {
     124            4 :         assert(GetLength() == sizeof(aValue));
     125            4 :         Encoding::BigEndian::Put16(GetValue(), aValue);
     126            4 :     }
     127              : 
     128           21 :     void SetValue(const void * aValue, size_t aLength)
     129              :     {
     130           21 :         assert(GetLength() == aLength);
     131           21 :         memcpy(GetValue(), aValue, aLength);
     132           21 :     }
     133              : 
     134            3 :     void SetValue(const ByteSpan & aValue) { SetValue(aValue.data(), aValue.size()); }
     135              : 
     136          278 :     const ThreadTLV * GetNext() const
     137              :     {
     138              :         static_assert(alignof(ThreadTLV) == 1, "Wrong alignment for ThreadTLV header");
     139          278 :         return reinterpret_cast<const ThreadTLV *>(static_cast<const uint8_t *>(GetValue()) + GetLength());
     140              :     }
     141              : 
     142            7 :     ThreadTLV * GetNext() { return reinterpret_cast<ThreadTLV *>(static_cast<uint8_t *>(GetValue()) + GetLength()); }
     143              : 
     144              : private:
     145              :     uint8_t mType;
     146              :     uint8_t mLength;
     147              : };
     148              : 
     149              : /// OperationalDatasetView
     150              : 
     151           12 : bool OperationalDatasetView::IsValid(ByteSpan aData)
     152              : {
     153           12 :     VerifyOrReturnValue(aData.size() <= kSizeOperationalDataset, false);
     154              : 
     155           11 :     const ThreadTLV * tlv = reinterpret_cast<const ThreadTLV *>(aData.begin());
     156           11 :     const ThreadTLV * end = reinterpret_cast<const ThreadTLV *>(aData.end());
     157           74 :     while (tlv != end)
     158              :     {
     159           65 :         VerifyOrReturnValue(tlv + 1 <= end, false);                               // out of bounds
     160           63 :         VerifyOrReturnValue(tlv->GetLength() != ThreadTLV::kLengthEscape, false); // not allowed in a dataset TLV
     161           63 :         tlv = tlv->GetNext();
     162              :     }
     163            9 :     return true;
     164              : }
     165              : 
     166            5 : CHIP_ERROR OperationalDatasetView::Init(ByteSpan aData)
     167              : {
     168            5 :     VerifyOrReturnError(IsValid(aData), CHIP_ERROR_INVALID_ARGUMENT);
     169            5 :     mData = aData;
     170            5 :     return CHIP_NO_ERROR;
     171              : }
     172              : 
     173           98 : const ThreadTLV * OperationalDatasetView::Locate(uint8_t aType) const
     174              : {
     175           98 :     const ThreadTLV * tlv = reinterpret_cast<const ThreadTLV *>(mData.begin());
     176           98 :     const ThreadTLV * end = reinterpret_cast<const ThreadTLV *>(mData.end());
     177          313 :     while (tlv < end)
     178              :     {
     179          279 :         if (tlv->GetType() == aType)
     180              :         {
     181           64 :             return tlv;
     182              :         }
     183          215 :         tlv = tlv->GetNext();
     184              :     }
     185           34 :     return nullptr;
     186              : }
     187              : 
     188            0 : bool OperationalDatasetView::IsCommissioned() const
     189              : {
     190            0 :     return Has(ThreadTLV::kPanId) && Has(ThreadTLV::kMasterKey) && Has(ThreadTLV::kExtendedPanId) && Has(ThreadTLV::kChannel);
     191              : }
     192              : 
     193            9 : CHIP_ERROR OperationalDatasetView::GetActiveTimestamp(uint64_t & aActiveTimestamp) const
     194              : {
     195            9 :     const ThreadTLV * tlv = Locate(ThreadTLV::kActiveTimestamp);
     196            9 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND);
     197            8 :     VerifyOrReturnError(tlv->GetLength() == sizeof(aActiveTimestamp), CHIP_ERROR_INVALID_TLV_ELEMENT);
     198            6 :     tlv->Get64(aActiveTimestamp);
     199            6 :     return CHIP_NO_ERROR;
     200              : }
     201              : 
     202            6 : CHIP_ERROR OperationalDatasetView::GetChannel(uint16_t & aChannel) const
     203              : {
     204            6 :     const ThreadTLV * tlv = Locate(ThreadTLV::kChannel);
     205            6 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND);
     206            5 :     VerifyOrReturnError(tlv->GetLength() == 3, CHIP_ERROR_INVALID_TLV_ELEMENT);
     207            3 :     const uint8_t * value = tlv->GetValue();
     208            3 :     VerifyOrReturnError(value[0] == 0, CHIP_ERROR_INVALID_TLV_ELEMENT); // Channel Page must be 0
     209            3 :     aChannel = Encoding::BigEndian::Get16(value + 1);
     210            3 :     return CHIP_NO_ERROR;
     211              : }
     212              : 
     213            4 : CHIP_ERROR OperationalDatasetView::GetExtendedPanId(uint8_t (&aExtendedPanId)[kSizeExtendedPanId]) const
     214              : {
     215            4 :     ByteSpan extPanIdSpan;
     216            4 :     ReturnErrorOnFailure(GetExtendedPanIdAsByteSpan(extPanIdSpan));
     217            3 :     memcpy(aExtendedPanId, extPanIdSpan.data(), extPanIdSpan.size());
     218            3 :     return CHIP_NO_ERROR;
     219              : }
     220              : 
     221            0 : CHIP_ERROR OperationalDatasetView::GetExtendedPanId(uint64_t & extendedPanId) const
     222              : {
     223            0 :     ByteSpan extPanIdSpan;
     224            0 :     ReturnErrorOnFailure(GetExtendedPanIdAsByteSpan(extPanIdSpan));
     225            0 :     VerifyOrDie(extPanIdSpan.size() == sizeof(extendedPanId));
     226            0 :     extendedPanId = Encoding::BigEndian::Get64(extPanIdSpan.data());
     227            0 :     return CHIP_NO_ERROR;
     228              : }
     229              : 
     230            7 : CHIP_ERROR OperationalDatasetView::GetExtendedPanIdAsByteSpan(ByteSpan & span) const
     231              : {
     232            7 :     const ThreadTLV * tlv = Locate(ThreadTLV::kExtendedPanId);
     233            7 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND);
     234            6 :     VerifyOrReturnError(tlv->GetLength() == kSizeExtendedPanId, CHIP_ERROR_INVALID_TLV_ELEMENT);
     235            4 :     span = tlv->GetValueAsSpan();
     236            4 :     return CHIP_NO_ERROR;
     237              : }
     238              : 
     239            6 : CHIP_ERROR OperationalDatasetView::GetMeshLocalPrefix(uint8_t (&aMeshLocalPrefix)[kSizeMeshLocalPrefix]) const
     240              : {
     241            6 :     const ThreadTLV * tlv = Locate(ThreadTLV::kMeshLocalPrefix);
     242            6 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND);
     243            5 :     VerifyOrReturnError(tlv->GetLength() == sizeof(aMeshLocalPrefix), CHIP_ERROR_INVALID_TLV_ELEMENT);
     244            3 :     memcpy(aMeshLocalPrefix, tlv->GetValue(), sizeof(aMeshLocalPrefix));
     245            3 :     return CHIP_NO_ERROR;
     246              : }
     247              : 
     248            7 : CHIP_ERROR OperationalDatasetView::GetMasterKey(uint8_t (&aMasterKey)[kSizeMasterKey]) const
     249              : {
     250            7 :     const ThreadTLV * tlv = Locate(ThreadTLV::kMasterKey);
     251            7 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND);
     252            5 :     VerifyOrReturnError(tlv->GetLength() == sizeof(aMasterKey), CHIP_ERROR_INVALID_TLV_ELEMENT);
     253            3 :     memcpy(aMasterKey, tlv->GetValue(), sizeof(aMasterKey));
     254            3 :     return CHIP_NO_ERROR;
     255              : }
     256              : 
     257            8 : CHIP_ERROR OperationalDatasetView::GetNetworkName(char (&aNetworkName)[kSizeNetworkName + 1]) const
     258              : {
     259            8 :     const ThreadTLV * tlv = Locate(ThreadTLV::kNetworkName);
     260            8 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND);
     261            7 :     VerifyOrReturnError(tlv->GetLength() <= kSizeNetworkName, CHIP_ERROR_INVALID_TLV_ELEMENT);
     262            5 :     memcpy(aNetworkName, tlv->GetValue(), tlv->GetLength());
     263            5 :     aNetworkName[tlv->GetLength()] = '\0';
     264            5 :     return CHIP_NO_ERROR;
     265              : }
     266              : 
     267            8 : CHIP_ERROR OperationalDatasetView::GetPanId(uint16_t & aPanId) const
     268              : {
     269            8 :     const ThreadTLV * tlv = Locate(ThreadTLV::kPanId);
     270            8 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND);
     271            7 :     VerifyOrReturnError(tlv->GetLength() == sizeof(aPanId), CHIP_ERROR_INVALID_TLV_ELEMENT);
     272            5 :     tlv->Get16(aPanId);
     273            5 :     return CHIP_NO_ERROR;
     274              : }
     275              : 
     276            7 : CHIP_ERROR OperationalDatasetView::GetPSKc(uint8_t (&aPSKc)[kSizePSKc]) const
     277              : {
     278            7 :     const ThreadTLV * tlv = Locate(ThreadTLV::kPSKc);
     279            7 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND);
     280            5 :     VerifyOrReturnError(tlv->GetLength() == sizeof(aPSKc), CHIP_ERROR_INVALID_TLV_ELEMENT);
     281            3 :     memcpy(aPSKc, tlv->GetValue(), sizeof(aPSKc));
     282            3 :     return CHIP_NO_ERROR;
     283              : }
     284              : 
     285            4 : CHIP_ERROR OperationalDatasetView::GetChannelMask(ByteSpan & aChannelMask) const
     286              : {
     287            4 :     const ThreadTLV * tlv = Locate(ThreadTLV::kChannelMask);
     288            4 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND);
     289            4 :     VerifyOrReturnError(tlv->GetLength() > 0, CHIP_ERROR_INVALID_TLV_ELEMENT);
     290            2 :     aChannelMask = tlv->GetValueAsSpan();
     291            2 :     return CHIP_NO_ERROR;
     292              : }
     293              : 
     294            4 : CHIP_ERROR OperationalDatasetView::GetSecurityPolicy(uint32_t & aSecurityPolicy) const
     295              : {
     296            4 :     const ThreadTLV * tlv = Locate(ThreadTLV::kSecurityPolicy);
     297            4 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND);
     298            4 :     VerifyOrReturnError(tlv->GetLength() == sizeof(aSecurityPolicy), CHIP_ERROR_INVALID_TLV_ELEMENT);
     299            2 :     tlv->Get32(aSecurityPolicy);
     300            2 :     return CHIP_NO_ERROR;
     301              : }
     302              : 
     303            0 : CHIP_ERROR OperationalDatasetView::GetDelayTimer(uint32_t & aDelayMillis) const
     304              : {
     305            0 :     const ThreadTLV * tlv = Locate(ThreadTLV::kDelayTimer);
     306            0 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND);
     307            0 :     VerifyOrReturnError(tlv->GetLength() == sizeof(aDelayMillis), CHIP_ERROR_INVALID_TLV_ELEMENT);
     308            0 :     tlv->Get32(aDelayMillis);
     309            0 :     return CHIP_NO_ERROR;
     310              : }
     311              : 
     312              : /// OperationalDataset
     313              : 
     314              : inline constexpr size_t kMaxDatasetElementLength = kSizeOperationalDataset - sizeof(ThreadTLV);
     315              : 
     316            7 : CHIP_ERROR OperationalDataset::Init(ByteSpan aData)
     317              : {
     318            7 :     VerifyOrReturnError(IsValid(aData), CHIP_ERROR_INVALID_ARGUMENT);
     319              :     // Use memmove because aData could be a sub-span of AsByteSpan()
     320            4 :     memmove(mBuffer, aData.data(), aData.size());
     321            4 :     mData = ByteSpan(mBuffer, aData.size());
     322            4 :     return CHIP_NO_ERROR;
     323              : }
     324              : 
     325           32 : void OperationalDataset::CopyDataIfNecessary()
     326              : {
     327              :     // It's possible that mData points into an external buffer if someone has
     328              :     // called OperationalDatasetView::Init() instead of our copying version.
     329           32 :     if (mData.data() != mBuffer)
     330              :     {
     331            1 :         CopyData();
     332              :     }
     333           32 : }
     334              : 
     335            4 : void OperationalDataset::CopyData()
     336              : {
     337            4 :     memmove(mBuffer, mData.data(), mData.size());
     338            4 :     mData = ByteSpan(mBuffer, mData.size());
     339            4 : }
     340              : 
     341            7 : void OperationalDataset::Remove(ThreadTLV * tlv)
     342              : {
     343            7 :     size_t size      = tlv->GetSize();
     344            7 :     ThreadTLV * next = tlv->GetNext();
     345            7 :     memmove(tlv, next, static_cast<size_t>(mData.end() - reinterpret_cast<uint8_t *>(next)));
     346            7 :     mData = ByteSpan(mData.data(), mData.size() - size);
     347            7 : }
     348              : 
     349            2 : void OperationalDataset::Remove(uint8_t aType)
     350              : {
     351            2 :     CopyDataIfNecessary();
     352            2 :     ThreadTLV * tlv = const_cast<ThreadTLV *>(Locate(aType));
     353            2 :     if (tlv != nullptr)
     354              :     {
     355            2 :         Remove(tlv);
     356              :     }
     357            2 : }
     358              : 
     359              : // Inserts a TLV of the specified type and length into the dataset, replacing an existing TLV
     360              : // of the same type if one exists. Returns nullptr if there is not enough space.
     361           30 : ThreadTLV * OperationalDataset::InsertOrReplace(uint8_t aType, size_t aValueSize)
     362              : {
     363           30 :     assert(aValueSize <= kMaxDatasetElementLength); // callers check this or a tighter limit
     364           30 :     CopyDataIfNecessary();
     365           30 :     ThreadTLV * tlv = const_cast<ThreadTLV *>(Locate(aType));
     366           30 :     if (tlv != nullptr)
     367              :     {
     368            6 :         size_t tlvLength = tlv->GetLength();
     369            6 :         VerifyOrReturnValue(aValueSize != tlvLength, tlv); // re-use in place if same size
     370            5 :         VerifyOrReturnValue(aValueSize < tlvLength || mData.size() + aValueSize - tlvLength <= sizeof(mBuffer), nullptr);
     371            5 :         Remove(tlv); // we could grow or shrink in place instead, but this is simpler
     372              :     }
     373              :     else
     374              :     {
     375           24 :         VerifyOrReturnValue(mData.size() + sizeof(ThreadTLV) + aValueSize <= sizeof(mBuffer), nullptr);
     376              :     }
     377              : 
     378           27 :     tlv = reinterpret_cast<ThreadTLV *>(mBuffer + mData.size());
     379           27 :     tlv->SetType(aType);
     380           27 :     tlv->SetLength(static_cast<uint8_t>(aValueSize));
     381           27 :     mData = ByteSpan(mBuffer, mData.size() + tlv->GetSize());
     382           27 :     return tlv;
     383              : }
     384              : 
     385            3 : CHIP_ERROR OperationalDataset::SetActiveTimestamp(uint64_t aActiveTimestamp)
     386              : {
     387              :     static_assert(sizeof(aActiveTimestamp) <= kMaxDatasetElementLength);
     388            3 :     ThreadTLV * tlv = InsertOrReplace(ThreadTLV::kActiveTimestamp, sizeof(aActiveTimestamp));
     389            3 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY);
     390            3 :     tlv->Set64(aActiveTimestamp);
     391            3 :     return CHIP_NO_ERROR;
     392              : }
     393              : 
     394            2 : CHIP_ERROR OperationalDataset::SetChannel(uint16_t aChannel)
     395              : {
     396            2 :     uint8_t value[3] = { 0 }; // Channel Page is always 0
     397            2 :     Encoding::BigEndian::Put16(value + 1, aChannel);
     398              :     static_assert(sizeof(value) <= kMaxDatasetElementLength);
     399            2 :     ThreadTLV * tlv = InsertOrReplace(ThreadTLV::kChannel, sizeof(value));
     400            2 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY);
     401            2 :     tlv->SetValue(value, sizeof(value));
     402            2 :     return CHIP_NO_ERROR;
     403              : }
     404              : 
     405            2 : CHIP_ERROR OperationalDataset::SetExtendedPanId(const uint8_t (&aExtendedPanId)[kSizeExtendedPanId])
     406              : {
     407              :     static_assert(sizeof(aExtendedPanId) <= kMaxDatasetElementLength);
     408            2 :     ThreadTLV * tlv = InsertOrReplace(ThreadTLV::kExtendedPanId, sizeof(aExtendedPanId));
     409            2 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY);
     410            2 :     tlv->SetValue(aExtendedPanId, sizeof(aExtendedPanId));
     411            2 :     return CHIP_NO_ERROR;
     412              : }
     413              : 
     414            3 : CHIP_ERROR OperationalDataset::SetMasterKey(const uint8_t (&aMasterKey)[kSizeMasterKey])
     415              : {
     416              :     static_assert(sizeof(aMasterKey) <= kMaxDatasetElementLength);
     417            3 :     ThreadTLV * tlv = InsertOrReplace(ThreadTLV::kMasterKey, sizeof(aMasterKey));
     418            3 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY);
     419            3 :     tlv->SetValue(aMasterKey, sizeof(aMasterKey));
     420            3 :     return CHIP_NO_ERROR;
     421              : }
     422              : 
     423            1 : void OperationalDataset::UnsetMasterKey()
     424              : {
     425            1 :     Remove(ThreadTLV::kMasterKey);
     426            1 : }
     427              : 
     428            2 : CHIP_ERROR OperationalDataset::SetMeshLocalPrefix(const uint8_t (&aMeshLocalPrefix)[kSizeMeshLocalPrefix])
     429              : {
     430              :     static_assert(sizeof(aMeshLocalPrefix) <= kMaxDatasetElementLength);
     431            2 :     ThreadTLV * tlv = InsertOrReplace(ThreadTLV::kMeshLocalPrefix, sizeof(aMeshLocalPrefix));
     432            2 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY);
     433            2 :     tlv->SetValue(aMeshLocalPrefix, sizeof(aMeshLocalPrefix));
     434            2 :     return CHIP_NO_ERROR;
     435              : }
     436              : 
     437            9 : CHIP_ERROR OperationalDataset::SetNetworkName(const char * aNetworkName)
     438              : {
     439            9 :     VerifyOrReturnError(aNetworkName != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     440            8 :     size_t len = strlen(aNetworkName);
     441            8 :     VerifyOrReturnError(0 < len && len <= kSizeNetworkName, CHIP_ERROR_INVALID_STRING_LENGTH);
     442              : 
     443              :     static_assert(kSizeNetworkName <= kMaxDatasetElementLength);
     444            6 :     ThreadTLV * tlv = InsertOrReplace(ThreadTLV::kNetworkName, len);
     445            6 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY);
     446            6 :     tlv->SetValue(aNetworkName, len);
     447            6 :     return CHIP_NO_ERROR;
     448              : }
     449              : 
     450            6 : CHIP_ERROR OperationalDataset::SetPanId(uint16_t aPanId)
     451              : {
     452              :     static_assert(sizeof(aPanId) <= kMaxDatasetElementLength);
     453            6 :     ThreadTLV * tlv = InsertOrReplace(ThreadTLV::kPanId, sizeof(aPanId));
     454            6 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY);
     455            4 :     tlv->Set16(aPanId);
     456            4 :     return CHIP_NO_ERROR;
     457              : }
     458              : 
     459            3 : CHIP_ERROR OperationalDataset::SetPSKc(const uint8_t (&aPSKc)[kSizePSKc])
     460              : {
     461              :     static_assert(sizeof(aPSKc) <= kMaxDatasetElementLength);
     462            3 :     ThreadTLV * tlv = InsertOrReplace(ThreadTLV::kPSKc, sizeof(aPSKc));
     463            3 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY);
     464            3 :     tlv->SetValue(aPSKc, sizeof(aPSKc));
     465            3 :     return CHIP_NO_ERROR;
     466              : }
     467              : 
     468            1 : void OperationalDataset::UnsetPSKc()
     469              : {
     470            1 :     Remove(ThreadTLV::kPSKc);
     471            1 : }
     472              : 
     473            3 : CHIP_ERROR OperationalDataset::SetChannelMask(ByteSpan aChannelMask)
     474              : {
     475            3 :     VerifyOrReturnError(0 < aChannelMask.size() && aChannelMask.size() <= kMaxDatasetElementLength, CHIP_ERROR_INVALID_ARGUMENT);
     476            3 :     ThreadTLV * tlv = InsertOrReplace(ThreadTLV::kChannelMask, aChannelMask.size());
     477            3 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY);
     478            3 :     tlv->SetValue(aChannelMask);
     479            3 :     return CHIP_NO_ERROR;
     480              : }
     481              : 
     482            0 : CHIP_ERROR OperationalDataset::SetSecurityPolicy(uint32_t aSecurityPolicy)
     483              : {
     484              :     static_assert(sizeof(aSecurityPolicy) <= kMaxDatasetElementLength);
     485            0 :     ThreadTLV * tlv = InsertOrReplace(ThreadTLV::kSecurityPolicy, sizeof(aSecurityPolicy));
     486            0 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY);
     487            0 :     tlv->Set32(aSecurityPolicy);
     488            0 :     return CHIP_NO_ERROR;
     489              : }
     490              : 
     491            0 : CHIP_ERROR OperationalDataset::SetDelayTimer(uint32_t aDelayMillis)
     492              : {
     493              :     static_assert(sizeof(aDelayMillis) <= kMaxDatasetElementLength);
     494            0 :     ThreadTLV * tlv = InsertOrReplace(ThreadTLV::kDelayTimer, sizeof(aDelayMillis));
     495            0 :     VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY);
     496            0 :     tlv->Set32(aDelayMillis);
     497            0 :     return CHIP_NO_ERROR;
     498              : }
     499              : 
     500              : } // namespace Thread
     501              : } // namespace chip
        

Generated by: LCOV version 2.0-1