Matter SDK Coverage Report
Current view: top level - lib/support - ThreadOperationalDataset.h (source / functions) Coverage Total Hit
Test: SHA:da00cfb13e586707ec8d44ae49325a696d4a8855 Lines: 93.3 % 15 14
Test Date: 2025-08-16 07:11:35 Functions: 90.9 % 11 10

            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              : #pragma once
      19              : 
      20              : #include <stdint.h>
      21              : #include <stdio.h>
      22              : #include <stdlib.h>
      23              : 
      24              : #include <lib/core/CHIPCore.h>
      25              : #include <lib/support/Span.h>
      26              : 
      27              : namespace chip {
      28              : namespace Thread {
      29              : 
      30              : class ThreadTLV;
      31              : 
      32              : inline constexpr size_t kChannel_NotSpecified = UINT8_MAX;
      33              : inline constexpr size_t kPANId_NotSpecified   = UINT16_MAX;
      34              : 
      35              : /// The maximum size of a Thread operational dataset.
      36              : inline constexpr size_t kSizeOperationalDataset = 254;
      37              : 
      38              : inline constexpr size_t kSizeNetworkName     = 16;
      39              : inline constexpr size_t kSizeExtendedPanId   = 8;
      40              : inline constexpr size_t kSizeMasterKey       = 16;
      41              : inline constexpr size_t kSizeMeshLocalPrefix = 8;
      42              : inline constexpr size_t kSizePSKc            = 16;
      43              : 
      44              : class OperationalDataset;
      45              : 
      46              : /**
      47              :  * This class provides a read-only view of a Thread operational dataset.
      48              :  * The underlying data is not owned by this class, and must remain valid for the lifetime of the view.
      49              :  */
      50              : class OperationalDatasetView
      51              : {
      52              : public:
      53              :     OperationalDatasetView() = default;
      54              : 
      55              :     /**
      56              :      * Initializes the dataset view with the given data.
      57              :      * The data itself is not copied, so it must remain valid for the lifetime of the view.
      58              :      *
      59              :      * @param[in]   aData       The data to interpret as a Thread operational dataset.
      60              :      *
      61              :      * @retval CHIP_NO_ERROR                Successfully initialized the dataset.
      62              :      * @retval CHIP_ERROR_INVALID_ARGUMENT  The dataset length @p aLength is too long or @p data is corrupted.
      63              :      */
      64              :     CHIP_ERROR Init(ByteSpan aData);
      65              : 
      66              :     /**
      67              :      * Returns the ByteSpan underlying this view.
      68              :      */
      69           27 :     ByteSpan AsByteSpan() const { return mData; }
      70              : 
      71              :     /**
      72              :      * Retrieves the Active Timestamp from the dataset.
      73              :      *
      74              :      * @param[out]  aActiveTimestamp    A reference to receive the active timestamp.
      75              :      *
      76              :      * @retval CHIP_NO_ERROR                    Successfully retrieved the active timestamp.
      77              :      * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread active timestamp is not present in the dataset.
      78              :      * @retval CHIP_ERROR_INVALID_TLV_ELEMENT   If the TLV element is invalid.
      79              :      */
      80              :     CHIP_ERROR GetActiveTimestamp(uint64_t & aActiveTimestamp) const;
      81              : 
      82              :     /**
      83              :      * Retrieves the channel number from the dataset.
      84              :      *
      85              :      * Note that the underlying TLV consists of a 1 byte Channel Page, and a 2 byte Channel Number.
      86              :      * The Channel Page is not returned, as zero is currently the only valid value.
      87              :      * A non-zero Channel Page is treated as a CHIP_ERROR_INVALID_TLV_ELEMENT error
      88              :      *
      89              :      * @param[out]  aChannel    A reference to receive the channel.
      90              :      *
      91              :      * @retval CHIP_NO_ERROR                    Successfully retrieved the channel.
      92              :      * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread channel is not present in the dataset.
      93              :      * @retval CHIP_ERROR_INVALID_TLV_ELEMENT   If the TLV element is invalid.
      94              :      */
      95              :     CHIP_ERROR GetChannel(uint16_t & aChannel) const;
      96              : 
      97              :     /**
      98              :      * Retrieves the Extended PAN ID from the dataset.
      99              :      *
     100              :      * @param[out]  aExtendedPanId  A reference to receive the extended PAN ID.
     101              :      *
     102              :      * @retval CHIP_NO_ERROR                    Successfully retrieved the extended PAN ID.
     103              :      * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread extended PAN ID is not present in the dataset.
     104              :      * @retval CHIP_ERROR_INVALID_TLV_ELEMENT   If the TLV element is invalid.
     105              :      */
     106              :     CHIP_ERROR GetExtendedPanId(uint8_t (&aExtendedPanId)[kSizeExtendedPanId]) const;
     107              : 
     108              :     /**
     109              :      * Retrieves the Extended PAN ID from the dataset, interpreted as a big endian number.
     110              :      * @retval CHIP_NO_ERROR                    Successfully retrieved the extended PAN ID.
     111              :      * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread extended PAN ID is not present in the dataset.
     112              :      */
     113              :     CHIP_ERROR GetExtendedPanId(uint64_t & extendedPanId) const;
     114              : 
     115              :     /**
     116              :      * Retrieves a ByteSpan pointing to the Extended PAN ID within the dataset.
     117              :      * This can be used to pass the extended PAN ID to a cluster command without the use of external memory.
     118              :      *
     119              :      * Note: The returned span points must not be dereferenced beyond the lifetime of this object.
     120              :      *
     121              :      * @param[out]  span  A reference to receive the location of the extended PAN ID.
     122              :      *
     123              :      * @retval CHIP_NO_ERROR                    Successfully retrieved the extended PAN ID.
     124              :      * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread extended PAN ID is not present in the dataset.
     125              :      * @retval CHIP_ERROR_INVALID_TLV_ELEMENT   If the TLV element is invalid.
     126              :      */
     127              :     CHIP_ERROR GetExtendedPanIdAsByteSpan(ByteSpan & span) const;
     128              : 
     129              :     /**
     130              :      * Retrieves the Master Key from the dataset.
     131              :      *
     132              :      * @param[out]  aMasterKey  A reference to receive the master key.
     133              :      *
     134              :      * @retval CHIP_NO_ERROR                    Successfully retrieved the master key.
     135              :      * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread master key is not present in the dataset.
     136              :      * @retval CHIP_ERROR_INVALID_TLV_ELEMENT   If the TLV element is invalid.
     137              :      */
     138              :     CHIP_ERROR GetMasterKey(uint8_t (&aMasterKey)[kSizeMasterKey]) const;
     139              : 
     140              :     /**
     141              :      * Retrieves the Mesh Local Prefix from the dataset.
     142              :      *
     143              :      * @param[out]  aMeshLocalPrefix    A reference to receive the mesh local prefix.
     144              :      *
     145              :      * @retval CHIP_NO_ERROR                    Successfully retrieved the mesh local prefix.
     146              :      * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread mesh local prefix is not present in the dataset.
     147              :      * @retval CHIP_ERROR_INVALID_TLV_ELEMENT   If the TLV element is invalid.
     148              :      */
     149              :     CHIP_ERROR GetMeshLocalPrefix(uint8_t (&aMeshLocalPrefix)[kSizeMeshLocalPrefix]) const;
     150              : 
     151              :     /**
     152              :      * Retrieves the Network Name from the dataset.
     153              :      *
     154              :      * @param[out]  aNetworkName    A reference to receive the Thread network name.
     155              :      *
     156              :      * @retval CHIP_NO_ERROR                    Successfully retrieved the network name.
     157              :      * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread network name is not present in the dataset.
     158              :      * @retval CHIP_ERROR_INVALID_TLV_ELEMENT   If the TLV element is invalid.
     159              :      */
     160              :     CHIP_ERROR GetNetworkName(char (&aNetworkName)[kSizeNetworkName + 1]) const;
     161              : 
     162              :     /**
     163              :      * Retrieves the PAN ID from the dataset.
     164              :      *
     165              :      * @param[out]  aPanId  A reference to receive the PAN ID.
     166              :      *
     167              :      * @retval CHIP_NO_ERROR                    Successfully retrieved the PAN ID.
     168              :      * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread PAN ID is not present in the dataset.
     169              :      * @retval CHIP_ERROR_INVALID_TLV_ELEMENT   If the TLV element is invalid.
     170              :      */
     171              :     CHIP_ERROR GetPanId(uint16_t & aPanId) const;
     172              : 
     173              :     /**
     174              :      * Retrieves the Pre-Shared Key for the Commissioner (PSKc) from the dataset.
     175              :      *
     176              :      * @param[out]  aPSKc   A reference to receive the PSKc.
     177              :      *
     178              :      * @retval CHIP_NO_ERROR                    Successfully retrieved the PSKc.
     179              :      * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND     Thread PSKc is not present in the dataset.
     180              :      * @retval CHIP_ERROR_INVALID_TLV_ELEMENT   If the TLV element is invalid.
     181              :      */
     182              :     CHIP_ERROR GetPSKc(uint8_t (&aPSKc)[kSizePSKc]) const;
     183              : 
     184              :     /**
     185              :      * Retrieves a ByteSpan pointing to the Channel Mask within the dataset.
     186              :      *
     187              :      * Note: The returned span must not be dereferenced beyond the lifetime of this object.
     188              :      *
     189              :      * @retval CHIP_NO_ERROR on success.
     190              :      * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND if the channel mask is not present in the dataset.
     191              :      * @retval CHIP_ERROR_INVALID_TLV_ELEMENT if the TLV element is invalid.
     192              :      */
     193              :     CHIP_ERROR GetChannelMask(ByteSpan & aChannelMask) const;
     194              : 
     195              :     /**
     196              :      * Retrieves the Security Policy from the dataset.
     197              :      *
     198              :      * @retval CHIP_NO_ERROR on success.
     199              :      * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND if no security policy is present in the dataset.
     200              :      * @retval CHIP_ERROR_INVALID_TLV_ELEMENT if the TLV element is invalid.
     201              :      */
     202              :     CHIP_ERROR GetSecurityPolicy(uint32_t & aSecurityPolicy) const;
     203              : 
     204              :     /**
     205              :      * Retrieves the Delay Timer from the dataset.
     206              :      *
     207              :      * @retval CHIP_NO_ERROR on success.
     208              :      * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND if no security policy is present in the dataset.
     209              :      * @retval CHIP_ERROR_INVALID_TLV_ELEMENT if the TLV element is invalid.
     210              :      */
     211              :     CHIP_ERROR GetDelayTimer(uint32_t & aDelayMillis) const;
     212              : 
     213              :     /**
     214              :      * Returns true if the dataset contains the required TLV elements for creating a Thread network.
     215              :      * The required elements are: PAN ID, Extended PAN ID, Channel, and Master Key.
     216              :      */
     217              :     bool IsCommissioned() const;
     218              : 
     219              :     /**
     220              :      * This method checks if the dataset is empty.
     221              :      */
     222            2 :     bool IsEmpty() const { return mData.empty(); }
     223              : 
     224              :     /**
     225              :      * This method checks whether @p aData contains a valid sequence of Thread TLV elements.
     226              :      *
     227              :      * @note This method only verifies the overall TLV format, not the correctness of individual TLV elements.
     228              :      */
     229              :     static bool IsValid(ByteSpan aData);
     230              : 
     231              : private:
     232              :     friend class OperationalDataset;
     233              : 
     234              :     ByteSpan mData;
     235              : 
     236          175 :     OperationalDatasetView(uint8_t * buffer) : mData(ByteSpan(buffer, 0)) {}
     237              : 
     238              :     const ThreadTLV * Locate(uint8_t aType) const;
     239            0 :     bool Has(uint8_t aType) const { return Locate(aType) != nullptr; }
     240              : };
     241              : 
     242              : /**
     243              :  * This class provides methods to manipulate a Thread operational dataset.
     244              :  * It maintains an internal buffer sized to accommodate the maximum possible dataset size.
     245              :  */
     246              : class OperationalDataset : public OperationalDatasetView
     247              : {
     248              : public:
     249          175 :     OperationalDataset() : OperationalDatasetView(mBuffer) {}
     250              : 
     251              :     // Delegate copy construction and assignment to the overloads taking an OperationalDatasetView.
     252            1 :     OperationalDataset(const OperationalDataset & other) : OperationalDataset(static_cast<const OperationalDatasetView &>(other)) {}
     253            1 :     OperationalDataset & operator=(const OperationalDataset & other)
     254              :     {
     255            1 :         return *this = static_cast<const OperationalDatasetView &>(other);
     256              :     }
     257              : 
     258            1 :     OperationalDataset(const OperationalDatasetView & view) : OperationalDatasetView(view) { CopyData(); }
     259            2 :     OperationalDataset & operator=(const OperationalDatasetView & view)
     260              :     {
     261            2 :         static_cast<OperationalDatasetView &>(*this) = view;
     262            2 :         CopyData();
     263            2 :         return *this;
     264              :     }
     265              : 
     266              :     /**
     267              :      * Initializes the dataset by copying the provided data into an internal buffer.
     268              :      *
     269              :      * @param[in]   aData       The data to interpret as a Thread operational dataset.
     270              :      *
     271              :      * @retval CHIP_NO_ERROR                Successfully initialized the dataset.
     272              :      * @retval CHIP_ERROR_INVALID_ARGUMENT  The dataset length @p aLength is too long or @p data is corrupted.
     273              :      */
     274              :     CHIP_ERROR Init(ByteSpan aData);
     275              : 
     276              :     /**
     277              :      * Sets the Active Timestamp in the dataset.
     278              :      *
     279              :      * @param[in]   aActiveTimestamp    The Thread active timestamp.
     280              :      *
     281              :      * @retval CHIP_NO_ERROR           Successfully set the active timestamp.
     282              :      * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread active timestamp.
     283              :      */
     284              :     CHIP_ERROR SetActiveTimestamp(uint64_t aActiveTimestamp);
     285              : 
     286              :     /**
     287              :      * Sets the Channel Number in the dataset.
     288              :      *
     289              :      * Note that the underlying TLV consists of a 1 byte Channel Page, and a 2 byte Channel Number.
     290              :      * The Channel Page is always set to zero, as it is currently the only valid value.
     291              :      *
     292              :      * @param[in]   aChannel    The Thread channel.
     293              :      *
     294              :      * @retval CHIP_NO_ERROR           Successfully set the channel.
     295              :      * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread channel.
     296              :      */
     297              :     CHIP_ERROR SetChannel(uint16_t aChannel);
     298              : 
     299              :     /**
     300              :      * Sets the Extended PAN ID in the dataset.
     301              :      *
     302              :      * @param[in]   aExtendedPanId  The Thread extended PAN ID.
     303              :      *
     304              :      * @retval CHIP_NO_ERROR           Successfully set the extended PAN ID.
     305              :      * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread extended PAN ID.
     306              :      */
     307              :     CHIP_ERROR SetExtendedPanId(const uint8_t (&aExtendedPanId)[kSizeExtendedPanId]);
     308              : 
     309              :     /**
     310              :      * Sets the Master Key in the dataset.
     311              :      *
     312              :      * @param[in]   aMasterKey         The Thread master key.
     313              :      *
     314              :      * @retval CHIP_NO_ERROR           Successfully set the master key.
     315              :      * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread master key.
     316              :      */
     317              :     CHIP_ERROR SetMasterKey(const uint8_t (&aMasterKey)[kSizeMasterKey]);
     318              : 
     319              :     /**
     320              :      * Removes the Master Key from the dataset.
     321              :      */
     322              :     void UnsetMasterKey();
     323              : 
     324              :     /**
     325              :      * Sets the Mesh Local Prefix in the dataset.
     326              :      *
     327              :      * @param[in]   aMeshLocalPrefix   The Thread mesh local prefix.
     328              :      *
     329              :      * @retval CHIP_NO_ERROR           Successfully set the Thread mesh local prefix.
     330              :      * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread mesh local prefix.
     331              :      */
     332              :     CHIP_ERROR SetMeshLocalPrefix(const uint8_t (&aMeshLocalPrefix)[kSizeMeshLocalPrefix]);
     333              : 
     334              :     /**
     335              :      * Sets the Network Name in the dataset. The name must be a non-empty string
     336              :      * with a maximum length of 16 characters (kSizeNetworkName).
     337              :      *
     338              :      * @param[in]   aNetworkName    The Thread network name.
     339              :      *
     340              :      * @retval CHIP_NO_ERROR           Successfully set the network name.
     341              :      * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread network name.
     342              :      */
     343              :     CHIP_ERROR SetNetworkName(const char * aNetworkName);
     344              : 
     345              :     /**
     346              :      * Sets the PAN ID in the dataset.
     347              :      *
     348              :      * @param[in]   aPanId  The Thread PAN ID.
     349              :      *
     350              :      * @retval CHIP_NO_ERROR           Successfully set the PAN ID.
     351              :      * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread PAN ID.
     352              :      */
     353              :     CHIP_ERROR SetPanId(uint16_t aPanId);
     354              : 
     355              :     /**
     356              :      * Sets the Pre-Shared Key for the Commissioner (PSKc) in the dataset.
     357              :      *
     358              :      * @param[in]   aPSKc   The Thread PSKc.
     359              :      *
     360              :      * @retval CHIP_NO_ERROR           Successfully set the PSKc.
     361              :      * @retval CHIP_ERROR_NO_MEMORY    Insufficient memory in the dataset for setting Thread PSKc.
     362              :      */
     363              :     CHIP_ERROR SetPSKc(const uint8_t (&aPSKc)[kSizePSKc]);
     364              : 
     365              :     /**
     366              :      * Removes the Pre-Shared Key for the Commissioner (PSKc) from the dataset.
     367              :      */
     368              :     void UnsetPSKc();
     369              : 
     370              :     /**
     371              :      * Sets the Channel Mask in the dataset. This value is a non-empty sequence of sub-TLVs as defined in the Thread specification.
     372              :      *
     373              :      * @retval CHIP_NO_ERROR on success.
     374              :      * @retval CHIP_ERROR_NO_MEMORY if there is insufficient space within the dataset.
     375              :      */
     376              :     CHIP_ERROR SetChannelMask(ByteSpan aChannelMask);
     377              : 
     378              :     /**
     379              :      * Sets the Security Policy in the dataset.
     380              :      *
     381              :      * @retval CHIP_NO_ERROR on success.
     382              :      * @retval CHIP_ERROR_NO_MEMORY if there is insufficient space within the dataset.
     383              :      */
     384              :     CHIP_ERROR SetSecurityPolicy(uint32_t aSecurityPolicy);
     385              : 
     386              :     /**
     387              :      * Sets the Delay Timer value in the dataset.
     388              :      *
     389              :      * @retval CHIP_NO_ERROR on success.
     390              :      * @retval CHIP_ERROR_NO_MEMORY if there is insufficient space within the dataset.
     391              :      */
     392              :     CHIP_ERROR SetDelayTimer(uint32_t aDelayMillis);
     393              : 
     394              :     /**
     395              :      * This method clears all data stored in the dataset.
     396              :      */
     397            2 :     void Clear() { mData = ByteSpan(mBuffer, 0); }
     398              : 
     399              :     /**
     400              :      * Returns a ByteSpan view of the current state of the dataset.
     401              :      * The byte span is only valid as long the OperationalDataset object is alive and not modified.
     402              :      */
     403           19 :     ByteSpan AsByteSpan() const { return this->OperationalDatasetView::AsByteSpan(); }
     404              : 
     405              : private:
     406              :     uint8_t mBuffer[kSizeOperationalDataset];
     407              : 
     408              :     void CopyData();
     409              :     void CopyDataIfNecessary();
     410              :     void Remove(uint8_t aType);
     411              :     void Remove(ThreadTLV * aTlv);
     412              :     ThreadTLV * InsertOrReplace(uint8_t aType, size_t aValueSize);
     413              : };
     414              : 
     415              : } // namespace Thread
     416              : } // namespace chip
        

Generated by: LCOV version 2.0-1