Matter SDK Coverage Report
Current view: top level - include/platform - NetworkCommissioning.h (source / functions) Coverage Total Hit
Test: SHA:e021a368d10ac6f3f201c101585146211fdcdaa2 Lines: 56.2 % 16 9
Test Date: 2026-02-13 08:13:38 Functions: 44.8 % 29 13

            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              : /**
      19              :  *    @file
      20              :  *      This file defines the CHIP Device Network Provisioning object.
      21              :  *
      22              :  */
      23              : 
      24              : #pragma once
      25              : 
      26              : #include <credentials/CHIPCert.h>
      27              : #include <crypto/CHIPCryptoPAL.h>
      28              : #include <lib/core/CHIPCore.h>
      29              : #include <lib/core/CHIPSafeCasts.h>
      30              : #include <lib/core/Optional.h>
      31              : #include <lib/support/ThreadOperationalDataset.h>
      32              : #include <lib/support/TypeTraits.h>
      33              : #include <lib/support/Variant.h>
      34              : #include <platform/CHIPDeviceConfig.h>
      35              : #include <platform/internal/DeviceNetworkInfo.h>
      36              : 
      37              : #include <app-common/zap-generated/cluster-enums.h>
      38              : 
      39              : #include <limits>
      40              : 
      41              : namespace chip {
      42              : namespace DeviceLayer {
      43              : /**
      44              :  * We are using a namespace here, for most use cases, this namespace will be used by `using DeviceLayer::NetworkCommissioning`, but
      45              :  * this still worth a dedicated namespace since:
      46              :  *
      47              :  * - The BaseDriver / WirelessDriver is not expected to be implemented directly by users, the only occurrence is in the network
      48              :  *   commissioning cluster.
      49              :  * - We can safely name the drivers as WiFiDriver / ThreadDriver, it should not be ambiguous for most cases
      50              :  * - We can safely name the Status enum to Status, and some other structs -- if we are using using, then we should in the context of
      51              :  *   writing something dedicated to network commissioning, then a single word Status should be clear enough.
      52              :  */
      53              : namespace NetworkCommissioning {
      54              : 
      55              : inline constexpr size_t kMaxNetworkIDLen = 32;
      56              : 
      57              : // TODO: This is exactly the same as the one in GroupDataProvider, this could be moved to src/lib/support
      58              : template <typename T>
      59              : class Iterator
      60              : {
      61              : public:
      62            3 :     virtual ~Iterator() = default;
      63              :     /**
      64              :      *  @retval The number of entries in total that will be iterated.
      65              :      */
      66              :     virtual size_t Count() = 0;
      67              :     /**
      68              :      *   @param[out] item  Value associated with the next element in the iteration.
      69              :      *  @retval true if the next entry is successfully retrieved.
      70              :      *  @retval false if no more entries can be found.
      71              :      */
      72              :     virtual bool Next(T & item) = 0;
      73              :     /**
      74              :      * Release the memory allocated by this iterator.
      75              :      * Must be called before the pointer goes out of scope.
      76              :      */
      77              :     virtual void Release() = 0;
      78              : 
      79              : protected:
      80            3 :     Iterator() = default;
      81              : };
      82              : 
      83              : // The following structs follows the generated cluster object structs.
      84              : struct Network
      85              : {
      86              :     uint8_t networkID[kMaxNetworkIDLen];
      87              :     uint8_t networkIDLen = 0;
      88              : #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC
      89              :     Optional<Credentials::CertificateKeyIdStorage> networkIdentifier;
      90              :     Optional<Credentials::CertificateKeyIdStorage> clientIdentifier;
      91              : #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC
      92              :     bool connected = false;
      93              : };
      94              : 
      95              : static_assert(sizeof(Network::networkID) <= std::numeric_limits<decltype(Network::networkIDLen)>::max(),
      96              :               "Max length of networkID ssid exceeds the limit of networkIDLen field");
      97              : 
      98              : /**
      99              :  *  Wireless signal strength assessment or measurement type.
     100              :  */
     101              : enum class WirelessSignalType
     102              : {
     103              :     /**
     104              :      *  No signal strength information available.
     105              :      */
     106              :     kNone,
     107              : 
     108              :     /**
     109              :      *  Signal strength is quantitative, in dBm.
     110              :      */
     111              :     kdBm,
     112              : 
     113              :     /**
     114              :      *  Signal strength is qualitative, increasing from 0 (none/worst)
     115              :      *  to 100 (best).
     116              :      */
     117              :     kQualitative
     118              : };
     119              : 
     120              : /**
     121              :  *  Wireless signal type and strength assessment.
     122              :  */
     123              : struct WirelessSignal
     124              : {
     125              :     /**
     126              :      *  Wireless signal strength assessment or measurement type.
     127              :      *
     128              :      *  This determines how to interpret @a strength.
     129              :      */
     130              :     WirelessSignalType type;
     131              : 
     132              :     /**
     133              :      *  Wireless signal strength assessment or measurement.
     134              :      *
     135              :      *  This is interpretted based on @a type.
     136              :      */
     137              :     int8_t strength;
     138              : };
     139              : 
     140              : struct WiFiScanResponse
     141              : {
     142              :     chip::BitFlags<app::Clusters::NetworkCommissioning::WiFiSecurityBitmap> security;
     143              :     uint8_t ssid[DeviceLayer::Internal::kMaxWiFiSSIDLength];
     144              :     uint8_t ssidLen;
     145              :     uint8_t bssid[6];
     146              :     uint16_t channel;
     147              :     app::Clusters::NetworkCommissioning::WiFiBandEnum wiFiBand;
     148              :     WirelessSignal signal;
     149              : };
     150              : 
     151              : static_assert(sizeof(WiFiScanResponse::ssid) <= std::numeric_limits<decltype(WiFiScanResponse::ssidLen)>::max(),
     152              :               "Max length of WiFi ssid exceeds the limit of ssidLen field");
     153              : 
     154              : struct ThreadScanResponse
     155              : {
     156              :     uint16_t panId;
     157              :     uint64_t extendedPanId;
     158              :     char networkName[16];
     159              :     uint8_t networkNameLen;
     160              :     uint16_t channel;
     161              :     uint8_t version;
     162              :     uint64_t extendedAddress;
     163              :     int8_t rssi;
     164              :     uint8_t lqi;
     165              : };
     166              : 
     167              : static_assert(sizeof(ThreadScanResponse::networkName) <= std::numeric_limits<decltype(ThreadScanResponse::networkNameLen)>::max(),
     168              :               "Max length of WiFi credentials exceeds the limit of credentialsLen field");
     169              : 
     170              : using NetworkIterator            = Iterator<Network>;
     171              : using WiFiScanResponseIterator   = Iterator<WiFiScanResponse>;
     172              : using ThreadScanResponseIterator = Iterator<ThreadScanResponse>;
     173              : using Status                     = app::Clusters::NetworkCommissioning::NetworkCommissioningStatusEnum;
     174              : using WiFiBandEnum               = app::Clusters::NetworkCommissioning::WiFiBandEnum;
     175              : // For backwards compatibility with pre-rename enum values.
     176              : using WiFiBand           = WiFiBandEnum;
     177              : using WiFiSecurityBitmap = app::Clusters::NetworkCommissioning::WiFiSecurityBitmap;
     178              : // For backwards compatibility with pre-rename bitmap values.
     179              : using WiFiSecurity       = WiFiSecurityBitmap;
     180              : using ThreadCapabilities = app::Clusters::NetworkCommissioning::ThreadCapabilitiesBitmap;
     181              : 
     182              : // BaseDriver and WirelessDriver are the common interfaces for a network driver, platform drivers should not implement this
     183              : // directly, instead, users are expected to implement WiFiDriver, ThreadDriver and EthernetDriver.
     184              : namespace Internal {
     185              : class BaseDriver
     186              : {
     187              : public:
     188              :     class NetworkStatusChangeCallback
     189              :     {
     190              :     public:
     191              :         /**
     192              :          * @brief Callback for the network driver pushing the event of network status change to the network commissioning cluster.
     193              :          * The platforms is expected to push the status from operations such as autonomous connection after loss of connectivity or
     194              :          * during initial establishment.
     195              :          *
     196              :          * This function must be called in a thread-safe manner with CHIP stack.
     197              :          */
     198              :         virtual void OnNetworkingStatusChange(Status commissioningError, Optional<ByteSpan> networkId,
     199              :                                               Optional<int32_t> connectStatus) = 0;
     200              : 
     201            3 :         virtual ~NetworkStatusChangeCallback() = default;
     202              :     };
     203              : 
     204              :     /**
     205              :      * @brief Initializes the driver, this function will be called when initializing the network commissioning cluster.
     206              :      */
     207            0 :     virtual CHIP_ERROR Init(NetworkStatusChangeCallback * networkStatusChangeCallback) { return CHIP_NO_ERROR; }
     208              : 
     209              :     /**
     210              :      * @brief Shuts down the driver, this function will be called when shutting down the network commissioning cluster.
     211              :      */
     212            2 :     virtual void Shutdown() {}
     213              : 
     214              :     /**
     215              :      * @brief Returns maximum number of network configs can be added to the driver.
     216              :      */
     217              :     virtual uint8_t GetMaxNetworks() = 0;
     218              : 
     219              :     /**
     220              :      * @brief Returns an iterator for reading the networks, the user will always call NetworkIterator::Release. The iterator should
     221              :      * be consumed in the same context as calling GetNetworks(). Users must call Release() when the iterator goes out of scope.
     222              :      */
     223              :     virtual NetworkIterator * GetNetworks() = 0;
     224              : 
     225              :     /**
     226              :      * @brief Sets the status of the interface, this is an optional feature of a network driver.
     227              :      */
     228            0 :     virtual CHIP_ERROR SetEnabled(bool enabled) { return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; }
     229              : 
     230              :     /**
     231              :      * @brief Returns the status of the interface, this is an optional feature of a network driver the driver will be enabled by
     232              :      * default.
     233              :      */
     234            0 :     virtual bool GetEnabled() { return true; };
     235              : 
     236            3 :     virtual ~BaseDriver() = default;
     237              : };
     238              : 
     239              : class WirelessDriver : public Internal::BaseDriver
     240              : {
     241              : public:
     242              :     class ConnectCallback
     243              :     {
     244              :     public:
     245              :         virtual void OnResult(Status commissioningError, CharSpan debugText, int32_t connectStatus) = 0;
     246              : 
     247            3 :         virtual ~ConnectCallback() = default;
     248              :     };
     249              : 
     250              :     /**
     251              :      * @brief Persists the network configurations. This function is expected to be called when CommissioningComplete event is fired.
     252              :      */
     253              :     virtual CHIP_ERROR CommitConfiguration() = 0;
     254              : 
     255              :     /**
     256              :      * @brief Reverts the network configurations to the last committed one. This function is expected to be called when failsafe
     257              :      * timeout reached.
     258              :      */
     259              :     virtual CHIP_ERROR RevertConfiguration() = 0;
     260              : 
     261              :     virtual uint8_t GetScanNetworkTimeoutSeconds()    = 0;
     262              :     virtual uint8_t GetConnectNetworkTimeoutSeconds() = 0;
     263              : 
     264              :     /**
     265              :      * @brief Remove a network from the device. The driver should fill the outDebugText field to pass any human-readable messages to
     266              :      * the client. The driver should reduce the size of outDebugText to 0 to omit it from the response when no debug text needs to
     267              :      * be delivered. On success, the driver should set outNetworkIndex to the index of the network just removed. The value of
     268              :      * network index is discarded on failure.
     269              :      *
     270              :      * Note: The capacity of outDebugText passed by network commissioning cluster can be configured via
     271              :      * CHIP_CONFIG_NETWORK_COMMISSIONING_DEBUG_TEXT_BUFFER_SIZE.
     272              :      */
     273              :     virtual Status RemoveNetwork(ByteSpan networkId, MutableCharSpan & outDebugText, uint8_t & outNetworkIndex) = 0;
     274              : 
     275              :     /**
     276              :      * @brief Reorder the networks on the device. The driver should fill the outDebugText field to pass any human-readable messages
     277              :      * to the client. The driver should reduce the size of outDebugText to 0 to omit it from the response when no debug text needs
     278              :      * to be delivered.
     279              :      *
     280              :      * Note: The capacity of outDebugText passed by network commissioning cluster can be configured via
     281              :      * CHIP_CONFIG_NETWORK_COMMISSIONING_DEBUG_TEXT_BUFFER_SIZE.
     282              :      */
     283              :     virtual Status ReorderNetwork(ByteSpan networkId, uint8_t index, MutableCharSpan & outDebugText) = 0;
     284              : 
     285              :     /**
     286              :      * @brief Initializes a network join. callback->OnResult must be called, on both success and error. Callback can be
     287              :      * called inside ConnectNetwork.
     288              :      */
     289              :     virtual void ConnectNetwork(ByteSpan networkId, ConnectCallback * callback) = 0;
     290              : 
     291              : #if CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
     292              :     /**
     293              :      * @brief Disconnect from network, if currently connected.
     294              :      */
     295            0 :     virtual CHIP_ERROR DisconnectFromNetwork() { return CHIP_ERROR_NOT_IMPLEMENTED; }
     296              : #endif
     297              : };
     298              : } // namespace Internal
     299              : 
     300              : class WiFiDriver : public Internal::WirelessDriver
     301              : {
     302              : public:
     303              :     class ScanCallback
     304              :     {
     305              :     public:
     306              :         /**
     307              :          * Indicates the scan is finished, and accepts a iterator of networks discovered.
     308              :          * - networks can be nullptr when no networks discovered, or error occurred during scanning the networks.
     309              :          * OnFinished() must be called in a thread-safe manner with CHIP stack. (e.g. using ScheduleWork or ScheduleLambda)
     310              :          * - Users can assume the networks will always be used (and Release will be called) inside this function call. However, the
     311              :          * iterator might be not fully consumed (i.e. There are too many networks scanned to fit in the buffer for scan response
     312              :          * message.)
     313              :          */
     314              :         virtual void OnFinished(Status status, CharSpan debugText, WiFiScanResponseIterator * networks) = 0;
     315              : 
     316            3 :         virtual ~ScanCallback() = default;
     317              :     };
     318              : 
     319              :     /**
     320              :      * @brief Adds or updates a WiFi network on the device. The driver should fill the outDebugText field to pass any human-readable
     321              :      * messages to the client. The driver should reduce the size of outDebugText to 0 to omit it from the response when no debug
     322              :      * text needs to be delivered. On success, the driver should set outNetworkIndex to the index of the network just added or
     323              :      * updated. The value of network index is discarded on failure.
     324              :      *
     325              :      * Note: The capacity of outDebugText passed by network commissioning cluster can be configured via
     326              :      * CHIP_CONFIG_NETWORK_COMMISSIONING_DEBUG_TEXT_BUFFER_SIZE.
     327              :      */
     328              :     virtual Status AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, MutableCharSpan & outDebugText,
     329              :                                       uint8_t & outNetworkIndex) = 0;
     330              : 
     331              :     /**
     332              :      * @brief Initializes a WiFi network scan. callback->OnFinished must be called, on both success and error. Callback can
     333              :      * be called inside ScanNetworks.
     334              :      *
     335              :      * @param ssid        The interested SSID, the scanning SHALL be restricted to the given SSID if the ssid is not empty (i.e.
     336              :      *                    ssid.empty() is false).
     337              :      * @param callback    Callback that will be invoked upon finishing the scan
     338              :      */
     339              :     virtual void ScanNetworks(ByteSpan ssid, ScanCallback * callback) = 0;
     340              : 
     341              : #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC
     342              :     virtual bool SupportsPerDeviceCredentials() { return false; };
     343              : 
     344              :     /**
     345              :      * @brief Adds or updates a WiFi network with Per-Device Credentials on the device.
     346              :      *
     347              :      * @param ssid                          The SSID of the network to be added / updated.
     348              :      * @param networkIdentity               The Network Identity of the network, in compact-pdc-identity format.
     349              :      * @param clientIdentityNetworkIndex    If present, the index of the existing network configuration of which the Client
     350              :      *                                      Identity is to be re-used. Otherwise a new Client Identity shall be generated.
     351              :      * @param outStatus                     The application-level status code (Status::kSuccess on success).
     352              :      * @param outDebugText                  A debug text buffer that may be populated by the driver. The size of the span
     353              :      *                                      must be reduced to the length of text emitted (or 0, if none).
     354              :      * @param outClientIdentity             On success, the Client Identity that was generated or copied, depending on the
     355              :      *                                      presence of `clientIdentityNetworkIndex`.
     356              :      * @param outNextworkIndex              On success, the index of the network entry that was added or updated.
     357              :      *
     358              :      * @retval CHIP_NO_ERROR and outStatus == kSuccess on success.
     359              :      * @retval CHIP_NO_ERROR and outStatus != kSuccess for application-level errors. outDebugText should be populated.
     360              :      * @retval CHIP_ERROR_* on internal errors. None of the output parameters will be examined in this case.
     361              :      */
     362              :     virtual CHIP_ERROR AddOrUpdateNetworkWithPDC(ByteSpan ssid, ByteSpan networkIdentity,
     363              :                                                  Optional<uint8_t> clientIdentityNetworkIndex, Status & outStatus,
     364              :                                                  MutableCharSpan & outDebugText, MutableByteSpan & outClientIdentity,
     365              :                                                  uint8_t & outNetworkIndex)
     366              :     {
     367              :         return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
     368              :     }
     369              : 
     370              :     /**
     371              :      * @brief Retrieves the Network Identity associated with a network.
     372              :      *
     373              :      * @param networkIndex          The 0-based index of the network.
     374              :      * @param outNetworkIdentity    The output buffer to be populated with the Network
     375              :      *                              Identity in compact-pdc-identity TLV format.
     376              :      *
     377              :      * @return CHIP_NO_ERROR on success or a CHIP_ERROR on failure.
     378              :      */
     379              :     virtual CHIP_ERROR GetNetworkIdentity(uint8_t networkIndex, MutableByteSpan & outNetworkIdentity)
     380              :     {
     381              :         return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
     382              :     }
     383              : 
     384              :     /**
     385              :      * @brief Retrieves the Network Client Identity associated with a network.
     386              :      *
     387              :      * @param networkIndex          The 0-based index of the network.
     388              :      * @param outNetworkIdentity    The output buffer to be populated with the Network
     389              :      *                              Client Identity in compact-pdc-identity TLV format.
     390              :      *
     391              :      * @return CHIP_NO_ERROR on success or a CHIP_ERROR on failure.
     392              :      */
     393              :     virtual CHIP_ERROR GetClientIdentity(uint8_t networkIndex, MutableByteSpan & outClientIdentity)
     394              :     {
     395              :         return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
     396              :     }
     397              : 
     398              :     /**
     399              :      * @brief Signs the specified message with the private key of a Network Client Identity.
     400              :      */
     401              :     virtual CHIP_ERROR SignWithClientIdentity(uint8_t networkIndex, const ByteSpan & message,
     402              :                                               Crypto::P256ECDSASignature & outSignature)
     403              :     {
     404              :         return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
     405              :     }
     406              : #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC
     407              : 
     408              :     /**
     409              :      *  @brief Provide all the frequency bands supported by the Wi-Fi interface.
     410              :      *
     411              :      *  The default implementation returns the 2.4 GHz band support.
     412              :      *  Note: WiFi platforms should implement this function in their WiFiDriver to provide their complete device capabilities.
     413              :      *
     414              :      *  The returned bit mask has values of WiFiBandEnum packed into the bits. For example:
     415              :      *
     416              :      *    - Bit 0 = (WiFiBandEnum::k2g4 == 0) --> (1 << 0) == (1 << WiFiBandEnum::k2g4)
     417              :      *    - Bit 2 = (WiFiBandEnum::k5g == 2) --> (1 << 2) == (1 << WiFiBandEnum::k5g)
     418              :      *    - If both 2.4G and 5G are supported --> ((1 << k2g4) || (1 << k5g)) == (1 || 4) == 5
     419              :      *
     420              :      *  On error, return 0 (no bands supported). This should never happen... Note that
     421              :      *  certification tests will REQUIRE at least one bit set in the set.
     422              :      *
     423              :      *  @return a bitmask of supported Wi-Fi bands where each bit is associated with a WiFiBandEnum value.
     424              :      */
     425            0 :     virtual uint32_t GetSupportedWiFiBandsMask() const
     426              :     {
     427              :         // Default to 2.4G support (100% example platform coverage as of Matter 1.3) listed.
     428            0 :         return static_cast<uint32_t>(1UL << chip::to_underlying(WiFiBandEnum::k2g4));
     429              :     }
     430              : 
     431            2 :     ~WiFiDriver() override = default;
     432              : };
     433              : 
     434              : class ThreadDriver : public Internal::WirelessDriver
     435              : {
     436              : public:
     437              :     class ScanCallback
     438              :     {
     439              :     public:
     440              :         /**
     441              :          * Indicates the scan is finished, and accepts a iterator of networks discovered.
     442              :          * - networks can be nullptr when no networks discovered, or error occurred during scanning the networks.
     443              :          * OnFinished() must be called in a thread-safe manner with CHIP stack. (e.g. using ScheduleWork or ScheduleLambda)
     444              :          * - Users can assume the networks will always be used (and Release will be called) inside this function call. However, the
     445              :          * iterator might be not fully consumed (i.e. There are too many networks scanned to fit in the buffer for scan response
     446              :          * message.)
     447              :          */
     448              :         virtual void OnFinished(Status err, CharSpan debugText, ThreadScanResponseIterator * networks) = 0;
     449              : 
     450            3 :         virtual ~ScanCallback() = default;
     451              :     };
     452              : 
     453              :     /**
     454              :      * @brief Adds or updates a Thread network on the device. The driver should fill the outDebugText field to pass any
     455              :      * human-readable messages to the client. The driver should reduce the size of outDebugText to 0 to omit it from the response
     456              :      * when no debug text needs to be delivered. On success, the driver should set outNetworkIndex to the index of the network just
     457              :      * added or updated. The value of the network index is discarded on failure.
     458              :      *
     459              :      * Note: The capacity of outDebugText passed by network commissioning cluster can be configured via
     460              :      * CHIP_CONFIG_NETWORK_COMMISSIONING_DEBUG_TEXT_BUFFER_SIZE.
     461              :      */
     462              :     virtual Status AddOrUpdateNetwork(ByteSpan operationalDataset, MutableCharSpan & outDebugText, uint8_t & outNetworkIndex) = 0;
     463              : 
     464              :     /**
     465              :      * @brief Initializes a Thread network scan. callback->OnFinished must be called, on both success and error. Callback can
     466              :      * be called inside ScanNetworks.
     467              :      */
     468              :     virtual void ScanNetworks(ScanCallback * callback) = 0;
     469              : 
     470              :     /**
     471              :      * @brief Provide all of the Thread features supported by the Thread interface
     472              :      */
     473              :     virtual ThreadCapabilities GetSupportedThreadFeatures() = 0;
     474              : 
     475              :     /**
     476              :      * @brief Return the Thread version supported by the Thread interface
     477              :      */
     478              :     virtual uint16_t GetThreadVersion() = 0;
     479              : 
     480            0 :     ~ThreadDriver() override = default;
     481              : };
     482              : 
     483              : class EthernetDriver : public Internal::BaseDriver
     484              : {
     485              :     // Ethernet driver does not have any special operations.
     486              : };
     487              : 
     488              : } // namespace NetworkCommissioning
     489              : } // namespace DeviceLayer
     490              : } // namespace chip
        

Generated by: LCOV version 2.0-1