Matter SDK Coverage Report
Current view: top level - controller - CommissioningWindowOpener.h (source / functions) Coverage Total Hit
Test: SHA:6c8f029dd2432dc900f1c9245c324e69bd79e40a Lines: 100.0 % 4 4
Test Date: 2026-08-08 07:40:09 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /*
       2              :  *    Copyright (c) 2022 Project CHIP Authors
       3              :  *    All rights reserved.
       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 <app/OperationalSessionSetup.h>
      21              : #include <app/data-model/NullObject.h>
      22              : #include <controller/CHIPDeviceController.h>
      23              : #include <controller/CommissioningWindowParams.h>
      24              : #include <crypto/CHIPCryptoPAL.h>
      25              : #include <lib/core/CHIPCallback.h>
      26              : #include <lib/core/CHIPError.h>
      27              : #include <lib/core/NodeId.h>
      28              : #include <lib/core/Optional.h>
      29              : #include <platform/CHIPDeviceConfig.h>
      30              : #include <setup_payload/SetupPayload.h>
      31              : 
      32              : namespace chip {
      33              : namespace Controller {
      34              : 
      35              : /**
      36              :  * A helper class to open a commissioning window given some parameters.
      37              :  */
      38              : class CommissioningWindowOpener
      39              : {
      40              : public:
      41           12 :     CommissioningWindowOpener(DeviceController * controller) :
      42           12 :         mController(controller), mDeviceConnected(&OnDeviceConnectedCallback, this),
      43           24 :         mDeviceConnectionFailure(&OnDeviceConnectionFailureCallback, this)
      44           12 :     {}
      45              : 
      46              :     // mPBKDFSalt spans into this object's own mPBKDFSaltBuffer, so a copy would alias the source's.
      47              :     // Forbid copying explicitly, pinning the invariant to the buffer rather than to the Callback members.
      48              :     CommissioningWindowOpener(const CommissioningWindowOpener &)             = delete;
      49              :     CommissioningWindowOpener & operator=(const CommissioningWindowOpener &) = delete;
      50              : 
      51              :     enum class CommissioningWindowOption : uint8_t
      52              :     {
      53              :         kOriginalSetupCode = 0,
      54              :         kTokenWithRandomPIN,
      55              :         kTokenWithProvidedPIN,
      56              :     };
      57              : 
      58              :     /*
      59              :      * @brief
      60              :      *   Try to look up the device attached to our controller with the given
      61              :      *   node id and ask it to re-enter commissioning mode with its original
      62              :      *   PASE verifier, discriminator, etc. The device will exit commissioning
      63              :      *   mode after a successful commissioning, or after the given `timeout`
      64              :      *   time.
      65              :      *
      66              :      * @param[in] deviceId The device Id.
      67              :      * @param[in] timeout  The commissioning mode should terminate after this much time.
      68              :      * @param[in] callback The callback to call once the commissioning window is
      69              :      *                     open or if an error occurs.
      70              :      */
      71              :     CHIP_ERROR OpenBasicCommissioningWindow(NodeId deviceId, System::Clock::Seconds16 timeout,
      72              :                                             Callback::Callback<OnOpenBasicCommissioningWindow> * callback);
      73              : 
      74              :     /**
      75              :      * @brief
      76              :      *   Try to look up the device attached to our controller with the given
      77              :      *   node id and ask it to re-enter commissioning mode with a PASE verifier
      78              :      *   derived from the given information and the given discriminator. The
      79              :      *   device will exit commissioning mode after a successful commissioning,
      80              :      *   or after the given `timeout` time.
      81              :      *
      82              :      * @param[in] deviceId      The device Id.
      83              :      * @param[in] timeout       The commissioning mode should terminate after this much time.
      84              :      * @param[in] iteration     The PAKE iteration count associated with the PAKE Passcode ID and ephemeral
      85              :      *                          PAKE passcode verifier to be used for this commissioning.
      86              :      * @param[in] discriminator The long discriminator for the DNS-SD advertisement.
      87              :      * @param[in] setupPIN      The setup PIN to use, or NullOptional to use a randomly-generated one.
      88              :      * @param[in] salt          The salt to use, or NullOptional to use a
      89              :      *                          randomly-generated one.  If provided, must be at
      90              :      *                          least kSpake2p_Min_PBKDF_Salt_Length bytes and
      91              :      *                          at most kSpake2p_Max_PBKDF_Salt_Length bytes in
      92              :      *                          length.
      93              :      * @param[in] callback      The function to be called on success or failure of opening of commissioning window.
      94              :      * @param[out] payload      The setup payload, not including the VID/PID bits,
      95              :      *                          even if those were asked for, that is generated
      96              :      *                          based on the passed-in information.  The payload
      97              :      *                          provided to the callback function, unlike this
      98              :      *                          out parameter, will include the VID/PID bits if
      99              :      *                          readVIDPIDAttributes is true.
     100              :      *
     101              :      * @param[in] readVIDPIDAttributes Should the API internally read VID and PID from the device while opening the
     102              :      *                                 commissioning window.  If this argument is `true`, the API will read VID and
     103              :      *                                 PID from the device and include them in the setup payload passed to the
     104              :      *                                 callback.
     105              :      */
     106              :     CHIP_ERROR OpenCommissioningWindow(NodeId deviceId, System::Clock::Seconds16 timeout, uint32_t iteration,
     107              :                                        uint16_t discriminator, Optional<uint32_t> setupPIN, Optional<ByteSpan> salt,
     108              :                                        Callback::Callback<OnOpenCommissioningWindow> * callback, SetupPayload & payload,
     109              :                                        bool readVIDPIDAttributes = false);
     110              : 
     111              :     /**
     112              :      * @brief
     113              :      *   Try to look up the device attached to our controller with the given
     114              :      *   node id and ask it to re-enter commissioning mode with a PASE verifier
     115              :      *   derived from the given information and the given discriminator. The
     116              :      *   device will exit commissioning mode after a successful commissioning,
     117              :      *   or after the given `timeout` time.
     118              :      *
     119              :      * @param[in] params        The parameters required to open an enhanced commissioning window
     120              :      *                          with the provided or generated passcode.
     121              :      * @param[out] payload      The setup payload, not including the VID/PID bits,
     122              :      *                          even if those were asked for, that is generated
     123              :      *                          based on the passed-in information.  The payload
     124              :      *                          provided to the callback function, unlike this
     125              :      *                          out parameter, will include the VID/PID bits if
     126              :      *                          readVIDPIDAttributes is true.
     127              :      */
     128              :     CHIP_ERROR OpenCommissioningWindow(const CommissioningWindowPasscodeParams & params, SetupPayload & payload);
     129              : 
     130              : #if CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
     131              :     /**
     132              :      * @brief
     133              :      *   Try to look up the device attached to our controller with the given
     134              :      *   node id and ask it to enter joint commissioning mode with a PASE verifier
     135              :      *   derived from the given information and the given discriminator. The
     136              :      *   device will exit joint commissioning mode after a successful joint commissioning,
     137              :      *   or after the given `timeout` time.
     138              :      *
     139              :      * @param[in] params    The parameters required to open a joint commissioning window
     140              :      *                      with the provided passcode.
     141              :      * @param[out] payload  The setup payload, not including the VID/PID bits,
     142              :      *                      even if those were asked for, that is generated
     143              :      *                      based on the passed-in information.  The payload
     144              :      *                      provided to the callback function, unlike this
     145              :      *                      out parameter, will include the VID/PID bits if
     146              :      *                      readVIDPIDAttributes is true.
     147              :      */
     148              :     CHIP_ERROR OpenJointCommissioningWindow(const CommissioningWindowPasscodeParams & params, SetupPayload & payload);
     149              : #endif // CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
     150              : 
     151              :     /**
     152              :      * @brief
     153              :      *   Try to look up the device attached to our controller with the given
     154              :      *   node id and ask it to re-enter commissioning mode with a PASE verifier
     155              :      *   derived from the given information and the given discriminator. The
     156              :      *   device will exit commissioning mode after a successful commissioning,
     157              :      *   or after the given `timeout` time.
     158              :      *
     159              :      * @param[in] params    The parameters required to open an enhanced commissioning window
     160              :      *                      with the provided PAKE passcode verifier.
     161              :      */
     162              :     CHIP_ERROR OpenCommissioningWindow(const CommissioningWindowVerifierParams & params);
     163              : 
     164              : private:
     165              :     enum class Step : uint8_t
     166              :     {
     167              :         // Ready to start opening a commissioning window.
     168              :         kAcceptCommissioningStart,
     169              :         // Need to read VID.
     170              :         kReadVID,
     171              :         // Need to read PID.
     172              :         kReadPID,
     173              :         // Need to open commissioning window.
     174              :         kOpenCommissioningWindow,
     175              :     };
     176              : 
     177              :     CHIP_ERROR OpenCommissioningWindowInternal(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
     178              :     static void OnPIDReadResponse(void * context, uint16_t value);
     179              :     static void OnVIDReadResponse(void * context, VendorId value);
     180              :     static void OnVIDPIDReadFailureResponse(void * context, CHIP_ERROR error);
     181              :     static void OnOpenCommissioningWindowSuccess(void * context, const app::DataModel::NullObjectType &);
     182              :     static void OnOpenCommissioningWindowFailure(void * context, CHIP_ERROR error);
     183              :     static void OnDeviceConnectedCallback(void * context, Messaging::ExchangeManager & exchangeMgr,
     184              :                                           const SessionHandle & sessionHandle);
     185              :     static void OnDeviceConnectionFailureCallback(void * context, const ScopedNodeId & peerId, CHIP_ERROR error);
     186              : 
     187              :     DeviceController * const mController = nullptr;
     188              :     Step mNextStep                       = Step::kAcceptCommissioningStart;
     189              : 
     190              :     Callback::Callback<OnOpenCommissioningWindow> * mCommissioningWindowCallback                     = nullptr;
     191              :     Callback::Callback<OnOpenCommissioningWindowWithVerifier> * mCommissioningWindowVerifierCallback = nullptr;
     192              :     Callback::Callback<OnOpenBasicCommissioningWindow> * mBasicCommissioningWindowCallback           = nullptr;
     193              :     SetupPayload mSetupPayload;
     194              :     SetupDiscriminator mDiscriminator{};
     195              :     NodeId mNodeId               = kUndefinedNodeId;
     196              :     EndpointId mTargetEndpointId = kRootEndpointId; // Default endpoint for Administrator Commissioning Cluster
     197              :     System::Clock::Seconds16 mCommissioningWindowTimeout = System::Clock::kZero;
     198              :     CommissioningWindowOption mCommissioningWindowOption = CommissioningWindowOption::kOriginalSetupCode;
     199              :     Crypto::Spake2pVerifier mVerifier; // Used for non-basic commissioning.
     200              :     // Parameters needed for non-basic commissioning.
     201              :     uint32_t mPBKDFIterations = 0;
     202              :     uint8_t mPBKDFSaltBuffer[Crypto::kSpake2p_Max_PBKDF_Salt_Length];
     203              :     ByteSpan mPBKDFSalt;
     204              : 
     205              :     Callback::Callback<OnDeviceConnected> mDeviceConnected;
     206              :     Callback::Callback<OnDeviceConnectionFailure> mDeviceConnectionFailure;
     207              : 
     208              : #if CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
     209              :     bool mJointCommissioning = false;
     210              : #endif // CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
     211              : };
     212              : 
     213              : /**
     214              :  * A helper class that can be used by consumers that don't care about the callback from the
     215              :  * open-commissioning-window process and just want automatic cleanup of the CommissioningWindowOpener when done
     216              :  * with it.
     217              :  */
     218              : class AutoCommissioningWindowOpener : private CommissioningWindowOpener
     219              : {
     220              : public:
     221              :     // Takes the same arguments as CommissioningWindowOpener::OpenBasicCommissioningWindow except without the
     222              :     // callback.
     223              :     static CHIP_ERROR OpenBasicCommissioningWindow(DeviceController * controller, NodeId deviceId,
     224              :                                                    System::Clock::Seconds16 timeout);
     225              :     // Takes the same arguments as CommissioningWindowOpener::OpenCommissioningWindow except without the
     226              :     // callback.
     227              :     static CHIP_ERROR OpenCommissioningWindow(DeviceController * controller, NodeId deviceId, System::Clock::Seconds16 timeout,
     228              :                                               uint32_t iteration, uint16_t discriminator, Optional<uint32_t> setupPIN,
     229              :                                               Optional<ByteSpan> salt, SetupPayload & payload, bool readVIDPIDAttributes = false);
     230              : 
     231              : private:
     232              :     AutoCommissioningWindowOpener(DeviceController * controller);
     233              : 
     234              :     static void OnOpenCommissioningWindowResponse(void * context, NodeId deviceId, CHIP_ERROR status, chip::SetupPayload payload);
     235              :     static void OnOpenBasicCommissioningWindowResponse(void * context, NodeId deviceId, CHIP_ERROR status);
     236              : 
     237              :     chip::Callback::Callback<chip::Controller::OnOpenCommissioningWindow> mOnOpenCommissioningWindowCallback;
     238              :     chip::Callback::Callback<chip::Controller::OnOpenBasicCommissioningWindow> mOnOpenBasicCommissioningWindowCallback;
     239              : };
     240              : 
     241              : } // Namespace Controller
     242              : } // namespace chip
        

Generated by: LCOV version 2.0-1