LCOV - code coverage report
Current view: top level - controller - CommissioningDelegate.h (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 0 168 0.0 %
Date: 2024-02-15 08:20:41 Functions: 0 80 0.0 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  *    Copyright (c) 2021 Project CHIP Authors
       4             :  *    All rights reserved.
       5             :  *
       6             :  *    Licensed under the Apache License, Version 2.0 (the "License");
       7             :  *    you may not use this file except in compliance with the License.
       8             :  *    You may obtain a copy of the License at
       9             :  *
      10             :  *        http://www.apache.org/licenses/LICENSE-2.0
      11             :  *
      12             :  *    Unless required by applicable law or agreed to in writing, software
      13             :  *    distributed under the License is distributed on an "AS IS" BASIS,
      14             :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15             :  *    See the License for the specific language governing permissions and
      16             :  *    limitations under the License.
      17             :  */
      18             : 
      19             : #pragma once
      20             : #include <app-common/zap-generated/cluster-objects.h>
      21             : #include <app/OperationalSessionSetup.h>
      22             : #include <controller/CommissioneeDeviceProxy.h>
      23             : #include <credentials/attestation_verifier/DeviceAttestationDelegate.h>
      24             : #include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
      25             : #include <lib/support/Variant.h>
      26             : #include <system/SystemClock.h>
      27             : 
      28             : namespace chip {
      29             : namespace Controller {
      30             : 
      31             : class DeviceCommissioner;
      32             : 
      33             : enum CommissioningStage : uint8_t
      34             : {
      35             :     kError,
      36             :     kSecurePairing,              ///< Establish a PASE session with the device
      37             :     kReadCommissioningInfo,      ///< Query General Commissioning Attributes, Network Features and Time Synchronization Cluster
      38             :     kReadCommissioningInfo2,     ///< Query SupportsConcurrentConnection, ICD state, check for matching fabric
      39             :     kArmFailsafe,                ///< Send ArmFailSafe (0x30:0) command to the device
      40             :     kConfigRegulatory,           ///< Send SetRegulatoryConfig (0x30:2) command to the device
      41             :     kConfigureUTCTime,           ///< SetUTCTime if the DUT has a time cluster
      42             :     kConfigureTimeZone,          ///< Configure a time zone if one is required and available
      43             :     kConfigureDSTOffset,         ///< Configure DST offset if one is required and available
      44             :     kConfigureDefaultNTP,        ///< Configure a default NTP server if one is required and available
      45             :     kSendPAICertificateRequest,  ///< Send PAI CertificateChainRequest (0x3E:2) command to the device
      46             :     kSendDACCertificateRequest,  ///< Send DAC CertificateChainRequest (0x3E:2) command to the device
      47             :     kSendAttestationRequest,     ///< Send AttestationRequest (0x3E:0) command to the device
      48             :     kAttestationVerification,    ///< Verify AttestationResponse (0x3E:1) validity
      49             :     kSendOpCertSigningRequest,   ///< Send CSRRequest (0x3E:4) command to the device
      50             :     kValidateCSR,                ///< Verify CSRResponse (0x3E:5) validity
      51             :     kGenerateNOCChain,           ///< TLV encode Node Operational Credentials (NOC) chain certs
      52             :     kSendTrustedRootCert,        ///< Send AddTrustedRootCertificate (0x3E:11) command to the device
      53             :     kSendNOC,                    ///< Send AddNOC (0x3E:6) command to the device
      54             :     kConfigureTrustedTimeSource, ///< Configure a trusted time source if one is required and available (must be done after SendNOC)
      55             :     kICDGetRegistrationInfo,     ///< Waiting for the higher layer to provide ICD registraion informations.
      56             :     kICDRegistration,            ///< Register for ICD management
      57             :     kICDSendStayActive,          ///< Send Keep Alive to ICD
      58             :     kWiFiNetworkSetup,           ///< Send AddOrUpdateWiFiNetwork (0x31:2) command to the device
      59             :     kThreadNetworkSetup,         ///< Send AddOrUpdateThreadNetwork (0x31:3) command to the device
      60             :     kFailsafeBeforeWiFiEnable,   ///< Extend the fail-safe before doing kWiFiNetworkEnable
      61             :     kFailsafeBeforeThreadEnable, ///< Extend the fail-safe before doing kThreadNetworkEnable
      62             :     kWiFiNetworkEnable,          ///< Send ConnectNetwork (0x31:6) command to the device for the WiFi network
      63             :     kThreadNetworkEnable,        ///< Send ConnectNetwork (0x31:6) command to the device for the Thread network
      64             :     kFindOperational,            ///< Perform operational discovery and establish a CASE session with the device
      65             :     kSendComplete,               ///< Send CommissioningComplete (0x30:4) command to the device
      66             :     kCleanup,                    ///< Call delegates with status, free memory, clear timers and state
      67             :     /// Send ScanNetworks (0x31:0) command to the device.
      68             :     /// ScanNetworks can happen anytime after kArmFailsafe.
      69             :     /// However, the cirque tests fail if it is earlier in the list
      70             :     kScanNetworks,
      71             :     /// Waiting for the higher layer to provide network credentials before continuing the workflow.
      72             :     /// Call CHIPDeviceController::NetworkCredentialsReady() when CommissioningParameters is populated with
      73             :     /// network credentials to use in kWiFiNetworkSetup or kThreadNetworkSetup steps.
      74             :     kNeedsNetworkCreds,
      75             : };
      76             : 
      77             : enum ICDRegistrationStrategy : uint8_t
      78             : {
      79             :     kIgnore,         ///< Do not check whether the device is an ICD during commissioning
      80             :     kBeforeComplete, ///< Do commissioner self-registration or external controller registration,
      81             :                      ///< Controller should provide a ICDKey manager for generating symmetric key
      82             : };
      83             : 
      84             : const char * StageToString(CommissioningStage stage);
      85             : 
      86             : struct WiFiCredentials
      87             : {
      88             :     ByteSpan ssid;
      89             :     ByteSpan credentials;
      90           0 :     WiFiCredentials(ByteSpan newSsid, ByteSpan newCreds) : ssid(newSsid), credentials(newCreds) {}
      91             : };
      92             : 
      93             : struct NOCChainGenerationParameters
      94             : {
      95             :     ByteSpan nocsrElements;
      96             :     ByteSpan signature;
      97             : };
      98             : 
      99             : struct CompletionStatus
     100             : {
     101           0 :     CompletionStatus() : err(CHIP_NO_ERROR), failedStage(NullOptional), attestationResult(NullOptional) {}
     102             :     CHIP_ERROR err;
     103             :     Optional<CommissioningStage> failedStage;
     104             :     Optional<Credentials::AttestationVerificationResult> attestationResult;
     105             :     Optional<app::Clusters::GeneralCommissioning::CommissioningErrorEnum> commissioningError;
     106             :     Optional<app::Clusters::NetworkCommissioning::NetworkCommissioningStatusEnum> networkCommissioningStatus;
     107             : };
     108             : 
     109             : inline constexpr uint16_t kDefaultFailsafeTimeout = 60;
     110             : 
     111             : // Per spec, all commands that are sent with the failsafe armed need at least
     112             : // a 30s timeout.
     113             : inline constexpr System::Clock::Timeout kMinimumCommissioningStepTimeout = System::Clock::Seconds16(30);
     114             : 
     115             : class CommissioningParameters
     116             : {
     117             : public:
     118             :     static constexpr size_t kMaxThreadDatasetLen = 254;
     119             :     static constexpr size_t kMaxSsidLen          = 32;
     120             :     static constexpr size_t kMaxCredentialsLen   = 64;
     121             :     static constexpr size_t kMaxCountryCodeLen   = 2;
     122             : 
     123             :     // Value to use when setting the commissioning failsafe timer on the node being commissioned.
     124             :     // If the failsafe timer value is passed in as part of the commissioning parameters, that value will be used. If not supplied,
     125             :     // the AutoCommissioner will set this to the recommended value read from the node. If that is not set, it will fall back to the
     126             :     // default kDefaultFailsafeTimeout.
     127             :     // This value should be set before running PerformCommissioningStep for the kArmFailsafe step.
     128           0 :     const Optional<uint16_t> GetFailsafeTimerSeconds() const { return mFailsafeTimerSeconds; }
     129             : 
     130             :     // Value to use when re-setting the commissioning failsafe timer immediately prior to operational discovery.
     131             :     // If a CASE failsafe timer value is passed in as part of the commissioning parameters, then the failsafe timer
     132             :     // will be reset using this value before operational discovery begins. If not supplied, then the AutoCommissioner
     133             :     // will not automatically reset the failsafe timer before operational discovery begins. It can be useful for the
     134             :     // commissioner to set the CASE failsafe timer to a small value (ex. 30s) when the regular failsafe timer is set
     135             :     // to a larger value to accommodate user interaction during setup (network credential selection, user consent
     136             :     // after device attestation).
     137           0 :     const Optional<uint16_t> GetCASEFailsafeTimerSeconds() const { return mCASEFailsafeTimerSeconds; }
     138             : 
     139             :     // The location (indoor/outdoor) of the node being commissioned.
     140             :     // The node regulartory location (indoor/outdoor) should be set by the commissioner explicitly as it may be different than the
     141             :     // location of the commissioner. This location will be set on the node if the node supports configurable regulatory location
     142             :     // (from GetLocationCapability - see below). If the regulatory location is not supplied, this will fall back to the location in
     143             :     // GetDefaultRegulatoryLocation and then to Outdoor (most restrictive).
     144             :     // This value should be set before calling PerformCommissioningStep for the kConfigRegulatory step.
     145           0 :     const Optional<app::Clusters::GeneralCommissioning::RegulatoryLocationTypeEnum> GetDeviceRegulatoryLocation() const
     146             :     {
     147           0 :         return mDeviceRegulatoryLocation;
     148             :     }
     149             : 
     150             :     // Value to determine whether the node supports Concurrent Connections as read from the GeneralCommissioning cluster.
     151             :     // In the AutoCommissioner, this is automatically set from from the kReadCommissioningInfo2 stage.
     152           0 :     Optional<bool> GetSupportsConcurrentConnection() const { return mSupportsConcurrentConnection; }
     153             : 
     154             :     // The country code to be used for the node, if set.
     155           0 :     Optional<CharSpan> GetCountryCode() const { return mCountryCode; }
     156             : 
     157             :     // Time zone to set for the node
     158             :     // If required, this will be truncated to fit the max size allowable on the node
     159           0 :     Optional<app::DataModel::List<app::Clusters::TimeSynchronization::Structs::TimeZoneStruct::Type>> GetTimeZone() const
     160             :     {
     161           0 :         return mTimeZone;
     162             :     }
     163             : 
     164             :     // DST offset list. If required, this will be truncated to fit the max size allowable on the node
     165             :     // DST list will only be sent if the commissionee requires DST offsets, as indicated in the SetTimeZone response
     166           0 :     Optional<app::DataModel::List<app::Clusters::TimeSynchronization::Structs::DSTOffsetStruct::Type>> GetDSTOffsets() const
     167             :     {
     168           0 :         return mDSTOffsets;
     169             :     }
     170             : 
     171             :     // Default NTP to set on the node if supported and required
     172             :     // Default implementation will not overide a value already set on the commissionee
     173             :     // TODO: Add a force option?
     174           0 :     Optional<app::DataModel::Nullable<CharSpan>> GetDefaultNTP() const { return mDefaultNTP; }
     175             : 
     176             :     // Trusted time source
     177             :     // Default implementation will not override a value already set on the commissionee
     178             :     // TODO: Add a force option?
     179             :     Optional<app::DataModel::Nullable<app::Clusters::TimeSynchronization::Structs::FabricScopedTrustedTimeSourceStruct::Type>>
     180           0 :     GetTrustedTimeSource() const
     181             :     {
     182           0 :         return mTrustedTimeSource;
     183             :     }
     184             : 
     185             :     // Nonce sent to the node to use during the CSR request.
     186             :     // When using the AutoCommissioner, this value will be ignored in favour of the value supplied by the
     187             :     // OperationalCredentialsDelegate ObtainCsrNonce function. If the credential delegate is not supplied, the value supplied here
     188             :     // will be used. If neither is supplied random value will be used as a fallback.
     189             :     // This value must be set before calling PerformCommissioningStep for the kSendOpCertSigningRequest step.
     190           0 :     const Optional<ByteSpan> GetCSRNonce() const { return mCSRNonce; }
     191             : 
     192             :     // Nonce value sent to the node to use during the attestation request.
     193             :     // When using the AutoCommissioner, this value will fall back to random if not supplied.
     194             :     // If a non-random value is to be used, the value must be set before calling PerformCommissioningStep for the
     195             :     // kSendAttestationRequest step.
     196           0 :     const Optional<ByteSpan> GetAttestationNonce() const { return mAttestationNonce; }
     197             : 
     198             :     // WiFi SSID and credentials to use when adding/updating and enabling WiFi on the node.
     199             :     // This value must be set before calling PerformCommissioningStep for the kWiFiNetworkSetup or kWiFiNetworkEnable steps.
     200           0 :     const Optional<WiFiCredentials> GetWiFiCredentials() const { return mWiFiCreds; }
     201             : 
     202             :     // Thread operational dataset to use when adding/updating and enabling the thread network on the node.
     203             :     // This value must be set before calling PerformCommissioningStep for the kThreadNetworkSetup or kThreadNetworkEnable steps.
     204           0 :     const Optional<ByteSpan> GetThreadOperationalDataset() const { return mThreadOperationalDataset; }
     205             : 
     206             :     // The NOCSR parameters (elements and signature) returned from the node. In the AutoCommissioner, this is set using the data
     207             :     // returned from the kSendOpCertSigningRequest stage.
     208             :     // This value must be set before calling PerformCommissioningStep for the kGenerateNOCChain step.
     209           0 :     const Optional<NOCChainGenerationParameters> GetNOCChainGenerationParameters() const { return mNOCChainGenerationParameters; }
     210             : 
     211             :     // The root certificate for the operational certificate chain. In the auto commissioner, this is set by by the kGenerateNOCChain
     212             :     // stage through the OperationalCredentialsDelegate.
     213             :     // This value must be set before calling PerformCommissioningStep for the kSendTrustedRootCert step.
     214           0 :     const Optional<ByteSpan> GetRootCert() const { return mRootCert; }
     215             : 
     216             :     // The node operational certificate for the node being commissioned. In the AutoCommissioner, this is set by by the
     217             :     // kGenerateNOCChain stage through the OperationalCredentialsDelegate.
     218             :     // This value must be set before calling PerformCommissioningStep for the kSendNOC step.
     219             :     // This value must also be set before calling PerformCommissioningStep for the kSendTrustedRootCert step, as it is used to set
     220             :     // the node id in the DeviceProxy.
     221           0 :     const Optional<ByteSpan> GetNoc() const { return mNoc; }
     222             : 
     223             :     // The intermediate certificate for the node being commissioned. In the AutoCommissioner, this is set by by the
     224             :     // kGenerateNOCChain stage through the OperationalCredentialsDelegate.
     225             :     // This value should be set before calling PerformCommissioningStep for the kSendNOC step.
     226           0 :     const Optional<ByteSpan> GetIcac() const { return mIcac; }
     227             : 
     228             :     // Epoch key for the identity protection key for the node being commissioned. In the AutoCommissioner, this is set by by the
     229             :     // kGenerateNOCChain stage through the OperationalCredentialsDelegate.
     230             :     // This value must be set before calling PerformCommissioningStep for the kSendNOC step.
     231           0 :     const Optional<IdentityProtectionKeySpan> GetIpk() const
     232             :     {
     233           0 :         return mIpk.HasValue() ? Optional<IdentityProtectionKeySpan>(mIpk.Value().Span()) : Optional<IdentityProtectionKeySpan>();
     234             :     }
     235             : 
     236             :     // Admin subject id used for the case access control entry created if the AddNOC command succeeds. In the AutoCommissioner, this
     237             :     // is set by by the kGenerateNOCChain stage through the OperationalCredentialsDelegate.
     238             :     // This must be set before calling PerformCommissioningStep for the kSendNOC step.
     239           0 :     const Optional<NodeId> GetAdminSubject() const { return mAdminSubject; }
     240             : 
     241             :     // Attestation elements from the node. These are obtained from node in response to the AttestationRequest command. In the
     242             :     // AutoCommissioner, this is automatically set from the report from the kSendAttestationRequest stage.
     243             :     // This must be set before calling PerformCommissioningStep for the kAttestationVerification step.
     244           0 :     const Optional<ByteSpan> GetAttestationElements() const { return mAttestationElements; }
     245             : 
     246             :     // Attestation signature from the node. This is obtained from node in response to the AttestationRequest command. In the
     247             :     // AutoCommissioner, this is automatically set from the report from the kSendAttestationRequest stage.
     248             :     // This must be set before calling PerformCommissioningStep for the kAttestationVerification step.
     249           0 :     const Optional<ByteSpan> GetAttestationSignature() const { return mAttestationSignature; }
     250             : 
     251             :     // Product attestation intermediate certificate from the node. This is obtained from the node in response to the
     252             :     // CertificateChainRequest command for the PAI. In the AutoCommissioner, this is automatically set from the report from the
     253             :     // kSendPAICertificateRequest stage.
     254             :     // This must be set before calling PerformCommissioningStep for the kAttestationVerificationstep.
     255           0 :     const Optional<ByteSpan> GetPAI() const { return mPAI; }
     256             : 
     257             :     // Device attestation certificate from the node. This is obtained from the node in response to the CertificateChainRequest
     258             :     // command for the DAC. In the AutoCommissioner, this is automatically set from the report from the kSendDACCertificateRequest
     259             :     // stage.
     260             :     // This must be set before calling PerformCommissioningStep for the kAttestationVerification step.
     261           0 :     const Optional<ByteSpan> GetDAC() const { return mDAC; }
     262             : 
     263             :     // Node ID when a matching fabric is found in the Node Operational Credentials cluster.
     264             :     // In the AutoCommissioner, this is set from kReadCommissioningInfo stage.
     265             :     const Optional<NodeId> GetRemoteNodeId() const { return mRemoteNodeId; }
     266             : 
     267             :     // Node vendor ID from the basic information cluster. In the AutoCommissioner, this is automatically set from report from the
     268             :     // kReadCommissioningInfo stage.
     269             :     // This must be set before calling PerformCommissioningStep for the kAttestationVerification step.
     270           0 :     const Optional<VendorId> GetRemoteVendorId() const { return mRemoteVendorId; }
     271             : 
     272             :     // Node product ID from the basic information cluster. In the AutoCommissioner, this is automatically set from report from the
     273             :     // kReadCommissioningInfo stage.
     274             :     // This must be set before calling PerformCommissioningStep for the kAttestationVerification step.
     275           0 :     const Optional<uint16_t> GetRemoteProductId() const { return mRemoteProductId; }
     276             : 
     277             :     // Default regulatory location set by the node, as read from the GeneralCommissioning cluster. In the AutoCommissioner, this is
     278             :     // automatically set from report from the kReadCommissioningInfo stage.
     279             :     // This should be set before calling PerformCommissioningStep for the kConfigRegulatory step.
     280           0 :     const Optional<app::Clusters::GeneralCommissioning::RegulatoryLocationTypeEnum> GetDefaultRegulatoryLocation() const
     281             :     {
     282           0 :         return mDefaultRegulatoryLocation;
     283             :     }
     284             : 
     285             :     // Location capabilities of the node, as read from the GeneralCommissioning cluster. In the AutoCommissioner, this is
     286             :     // automatically set from report from the kReadCommissioningInfo stage.
     287             :     // This should be set before calling PerformCommissioningStep for the kConfigRegulatory step.
     288           0 :     const Optional<app::Clusters::GeneralCommissioning::RegulatoryLocationTypeEnum> GetLocationCapability() const
     289             :     {
     290           0 :         return mLocationCapability;
     291             :     }
     292             : 
     293             :     // Status to send when calling CommissioningComplete on the PairingDelegate during the kCleanup step. The AutoCommissioner uses
     294             :     // this to pass through any error messages received during commissioning.
     295           0 :     const CompletionStatus & GetCompletionStatus() const { return completionStatus; }
     296             : 
     297           0 :     CommissioningParameters & SetFailsafeTimerSeconds(uint16_t seconds)
     298             :     {
     299           0 :         mFailsafeTimerSeconds.SetValue(seconds);
     300           0 :         return *this;
     301             :     }
     302             : 
     303             :     CommissioningParameters & SetCASEFailsafeTimerSeconds(uint16_t seconds)
     304             :     {
     305             :         mCASEFailsafeTimerSeconds.SetValue(seconds);
     306             :         return *this;
     307             :     }
     308             : 
     309             :     CommissioningParameters & SetDeviceRegulatoryLocation(app::Clusters::GeneralCommissioning::RegulatoryLocationTypeEnum location)
     310             :     {
     311             :         mDeviceRegulatoryLocation.SetValue(location);
     312             :         return *this;
     313             :     }
     314             : 
     315           0 :     CommissioningParameters & SetSupportsConcurrentConnection(bool concurrentConnection)
     316             :     {
     317           0 :         mSupportsConcurrentConnection.SetValue(concurrentConnection);
     318           0 :         return *this;
     319             :     }
     320             : 
     321             :     // The lifetime of the buffer countryCode is pointing to should exceed the
     322             :     // lifetime of CommissioningParameters object.
     323           0 :     CommissioningParameters & SetCountryCode(CharSpan countryCode)
     324             :     {
     325           0 :         mCountryCode.SetValue(countryCode);
     326           0 :         return *this;
     327             :     }
     328             : 
     329             :     // The lifetime of the list buffer needs to exceed the lifetime of the CommissioningParameters object.
     330             :     CommissioningParameters &
     331           0 :     SetTimeZone(app::DataModel::List<app::Clusters::TimeSynchronization::Structs::TimeZoneStruct::Type> timeZone)
     332             :     {
     333           0 :         mTimeZone.SetValue(timeZone);
     334           0 :         return *this;
     335             :     }
     336             : 
     337             :     // The lifetime of the list buffer needs to exceed the lifetime of the CommissioningParameters object.
     338             :     CommissioningParameters &
     339           0 :     SetDSTOffsets(app::DataModel::List<app::Clusters::TimeSynchronization::Structs::DSTOffsetStruct::Type> dstOffsets)
     340             :     {
     341           0 :         mDSTOffsets.SetValue(dstOffsets);
     342           0 :         return *this;
     343             :     }
     344             : 
     345             :     // The lifetime of the char span needs to exceed the lifetime of the CommissioningParameters
     346           0 :     CommissioningParameters & SetDefaultNTP(app::DataModel::Nullable<CharSpan> defaultNTP)
     347             :     {
     348           0 :         mDefaultNTP.SetValue(defaultNTP);
     349           0 :         return *this;
     350             :     }
     351             : 
     352             :     CommissioningParameters & SetTrustedTimeSource(
     353             :         app::DataModel::Nullable<app::Clusters::TimeSynchronization::Structs::FabricScopedTrustedTimeSourceStruct::Type>
     354             :             trustedTimeSource)
     355             :     {
     356             :         mTrustedTimeSource.SetValue(trustedTimeSource);
     357             :         return *this;
     358             :     }
     359             : 
     360             :     // The lifetime of the buffer csrNonce is pointing to, should exceed the lifetime of CommissioningParameters object.
     361           0 :     CommissioningParameters & SetCSRNonce(ByteSpan csrNonce)
     362             :     {
     363           0 :         mCSRNonce.SetValue(csrNonce);
     364           0 :         return *this;
     365             :     }
     366             : 
     367             :     // The lifetime of the buffer attestationNonce is pointing to, should exceed the lifetime of CommissioningParameters object.
     368           0 :     CommissioningParameters & SetAttestationNonce(ByteSpan attestationNonce)
     369             :     {
     370           0 :         mAttestationNonce.SetValue(attestationNonce);
     371           0 :         return *this;
     372             :     }
     373           0 :     CommissioningParameters & SetWiFiCredentials(WiFiCredentials wifiCreds)
     374             :     {
     375           0 :         mWiFiCreds.SetValue(wifiCreds);
     376           0 :         return *this;
     377             :     }
     378             : 
     379             :     // If a ThreadOperationalDataset is provided, then the ThreadNetworkScan will not be attempted
     380           0 :     CommissioningParameters & SetThreadOperationalDataset(ByteSpan threadOperationalDataset)
     381             :     {
     382             : 
     383           0 :         mThreadOperationalDataset.SetValue(threadOperationalDataset);
     384           0 :         mAttemptThreadNetworkScan = MakeOptional(static_cast<bool>(false));
     385           0 :         return *this;
     386             :     }
     387             :     // This parameter should be set with the information returned from kSendOpCertSigningRequest. It must be set before calling
     388             :     // kGenerateNOCChain.
     389           0 :     CommissioningParameters & SetNOCChainGenerationParameters(const NOCChainGenerationParameters & params)
     390             :     {
     391           0 :         mNOCChainGenerationParameters.SetValue(params);
     392           0 :         return *this;
     393             :     }
     394             :     // Root certs can be generated from the kGenerateNOCChain step. This must be set before calling kSendTrustedRootCert.
     395           0 :     CommissioningParameters & SetRootCert(const ByteSpan & rcac)
     396             :     {
     397           0 :         mRootCert.SetValue(rcac);
     398           0 :         return *this;
     399             :     }
     400             :     // NOC and intermediate cert can be generated from the kGenerateNOCChain step. NOC must be set before calling
     401             :     // kSendTrustedRootCert. ICAC and NOC must be set before calling kSendNOC
     402           0 :     CommissioningParameters & SetNoc(const ByteSpan & noc)
     403             :     {
     404           0 :         mNoc.SetValue(noc);
     405           0 :         return *this;
     406             :     }
     407           0 :     CommissioningParameters & SetIcac(const ByteSpan & icac)
     408             :     {
     409           0 :         mIcac.SetValue(icac);
     410           0 :         return *this;
     411             :     }
     412           0 :     CommissioningParameters & SetIpk(const IdentityProtectionKeySpan ipk)
     413             :     {
     414           0 :         mIpk.SetValue(IdentityProtectionKey(ipk));
     415           0 :         return *this;
     416             :     }
     417           0 :     CommissioningParameters & SetAdminSubject(const NodeId adminSubject)
     418             :     {
     419           0 :         mAdminSubject.SetValue(adminSubject);
     420           0 :         return *this;
     421             :     }
     422           0 :     CommissioningParameters & SetAttestationElements(const ByteSpan & attestationElements)
     423             :     {
     424           0 :         mAttestationElements = MakeOptional(attestationElements);
     425           0 :         return *this;
     426             :     }
     427           0 :     CommissioningParameters & SetAttestationSignature(const ByteSpan & attestationSignature)
     428             :     {
     429           0 :         mAttestationSignature = MakeOptional(attestationSignature);
     430           0 :         return *this;
     431             :     }
     432           0 :     CommissioningParameters & SetPAI(const ByteSpan & pai)
     433             :     {
     434           0 :         mPAI = MakeOptional(pai);
     435           0 :         return *this;
     436             :     }
     437           0 :     CommissioningParameters & SetDAC(const ByteSpan & dac)
     438             :     {
     439           0 :         mDAC = MakeOptional(dac);
     440           0 :         return *this;
     441             :     }
     442           0 :     CommissioningParameters & SetRemoteNodeId(NodeId id)
     443             :     {
     444           0 :         mRemoteNodeId = MakeOptional(id);
     445           0 :         return *this;
     446             :     }
     447           0 :     CommissioningParameters & SetRemoteVendorId(VendorId id)
     448             :     {
     449           0 :         mRemoteVendorId = MakeOptional(id);
     450           0 :         return *this;
     451             :     }
     452           0 :     CommissioningParameters & SetRemoteProductId(uint16_t id)
     453             :     {
     454           0 :         mRemoteProductId = MakeOptional(id);
     455           0 :         return *this;
     456             :     }
     457           0 :     CommissioningParameters & SetDefaultRegulatoryLocation(app::Clusters::GeneralCommissioning::RegulatoryLocationTypeEnum location)
     458             :     {
     459           0 :         mDefaultRegulatoryLocation = MakeOptional(location);
     460           0 :         return *this;
     461             :     }
     462           0 :     CommissioningParameters & SetLocationCapability(app::Clusters::GeneralCommissioning::RegulatoryLocationTypeEnum capability)
     463             :     {
     464           0 :         mLocationCapability = MakeOptional(capability);
     465           0 :         return *this;
     466             :     }
     467           0 :     void SetCompletionStatus(const CompletionStatus & status) { completionStatus = status; }
     468             : 
     469             :     CommissioningParameters & SetDeviceAttestationDelegate(Credentials::DeviceAttestationDelegate * deviceAttestationDelegate)
     470             :     {
     471             :         mDeviceAttestationDelegate = deviceAttestationDelegate;
     472             :         return *this;
     473             :     }
     474             : 
     475           0 :     Credentials::DeviceAttestationDelegate * GetDeviceAttestationDelegate() const { return mDeviceAttestationDelegate; }
     476             : 
     477             :     // If an SSID is provided, and AttemptWiFiNetworkScan is true,
     478             :     // then a directed scan will be performed using the SSID provided in the WiFiCredentials object
     479           0 :     Optional<bool> GetAttemptWiFiNetworkScan() const { return mAttemptWiFiNetworkScan; }
     480             :     CommissioningParameters & SetAttemptWiFiNetworkScan(bool attemptWiFiNetworkScan)
     481             :     {
     482             :         mAttemptWiFiNetworkScan = MakeOptional(attemptWiFiNetworkScan);
     483             :         return *this;
     484             :     }
     485             : 
     486             :     // If a ThreadOperationalDataset is provided, then the ThreadNetworkScan will not be attempted
     487           0 :     Optional<bool> GetAttemptThreadNetworkScan() const { return mAttemptThreadNetworkScan; }
     488             :     CommissioningParameters & SetAttemptThreadNetworkScan(bool attemptThreadNetworkScan)
     489             :     {
     490             :         if (!mThreadOperationalDataset.HasValue())
     491             :         {
     492             :             mAttemptThreadNetworkScan = MakeOptional(attemptThreadNetworkScan);
     493             :         }
     494             :         return *this;
     495             :     }
     496             : 
     497             :     // Only perform the PASE steps of commissioning.
     498             :     // Commissioning will be completed by another admin on the network.
     499           0 :     Optional<bool> GetSkipCommissioningComplete() const { return mSkipCommissioningComplete; }
     500             :     CommissioningParameters & SetSkipCommissioningComplete(bool skipCommissioningComplete)
     501             :     {
     502             :         mSkipCommissioningComplete = MakeOptional(skipCommissioningComplete);
     503             :         return *this;
     504             :     }
     505             : 
     506             :     // Check for matching fabric on target device by reading fabric list and looking for a
     507             :     // fabricId and RootCert match. If a match is detected, then use GetNodeId() to
     508             :     // access the nodeId for the device on the matching fabric.
     509           0 :     bool GetCheckForMatchingFabric() const { return mCheckForMatchingFabric; }
     510             :     CommissioningParameters & SetCheckForMatchingFabric(bool checkForMatchingFabric)
     511             :     {
     512             :         mCheckForMatchingFabric = checkForMatchingFabric;
     513             :         return *this;
     514             :     }
     515             : 
     516           0 :     ICDRegistrationStrategy GetICDRegistrationStrategy() const { return mICDRegistrationStrategy; }
     517             :     CommissioningParameters & SetICDRegistrationStrategy(ICDRegistrationStrategy icdRegistrationStrategy)
     518             :     {
     519             :         mICDRegistrationStrategy = icdRegistrationStrategy;
     520             :         return *this;
     521             :     }
     522             : 
     523           0 :     Optional<NodeId> GetICDCheckInNodeId() const { return mICDCheckInNodeId; }
     524           0 :     CommissioningParameters & SetICDCheckInNodeId(NodeId icdCheckInNodeId)
     525             :     {
     526           0 :         mICDCheckInNodeId = MakeOptional(icdCheckInNodeId);
     527           0 :         return *this;
     528             :     }
     529             : 
     530           0 :     Optional<uint64_t> GetICDMonitoredSubject() const { return mICDMonitoredSubject; }
     531           0 :     CommissioningParameters & SetICDMonitoredSubject(uint64_t icdMonitoredSubject)
     532             :     {
     533           0 :         mICDMonitoredSubject = MakeOptional(icdMonitoredSubject);
     534           0 :         return *this;
     535             :     }
     536             : 
     537           0 :     Optional<ByteSpan> GetICDSymmetricKey() const { return mICDSymmetricKey; }
     538           0 :     CommissioningParameters & SetICDSymmetricKey(ByteSpan icdSymmetricKey)
     539             :     {
     540           0 :         mICDSymmetricKey = MakeOptional(icdSymmetricKey);
     541           0 :         return *this;
     542             :     }
     543             : 
     544             :     // Clear all members that depend on some sort of external buffer.  Can be
     545             :     // used to make sure that we are not holding any dangling pointers.
     546           0 :     void ClearExternalBufferDependentValues()
     547             :     {
     548           0 :         mCSRNonce.ClearValue();
     549           0 :         mAttestationNonce.ClearValue();
     550           0 :         mWiFiCreds.ClearValue();
     551           0 :         mCountryCode.ClearValue();
     552           0 :         mThreadOperationalDataset.ClearValue();
     553           0 :         mNOCChainGenerationParameters.ClearValue();
     554           0 :         mRootCert.ClearValue();
     555           0 :         mNoc.ClearValue();
     556           0 :         mIcac.ClearValue();
     557           0 :         mIpk.ClearValue();
     558           0 :         mAttestationElements.ClearValue();
     559           0 :         mAttestationSignature.ClearValue();
     560           0 :         mPAI.ClearValue();
     561           0 :         mDAC.ClearValue();
     562           0 :         mTimeZone.ClearValue();
     563           0 :         mDSTOffsets.ClearValue();
     564           0 :         mDefaultNTP.ClearValue();
     565           0 :         mICDSymmetricKey.ClearValue();
     566           0 :     }
     567             : 
     568             : private:
     569             :     // Items that can be set by the commissioner
     570             :     Optional<uint16_t> mFailsafeTimerSeconds;
     571             :     Optional<uint16_t> mCASEFailsafeTimerSeconds;
     572             :     Optional<app::Clusters::GeneralCommissioning::RegulatoryLocationTypeEnum> mDeviceRegulatoryLocation;
     573             :     Optional<app::DataModel::List<app::Clusters::TimeSynchronization::Structs::TimeZoneStruct::Type>> mTimeZone;
     574             :     Optional<app::DataModel::List<app::Clusters::TimeSynchronization::Structs::DSTOffsetStruct::Type>> mDSTOffsets;
     575             :     Optional<app::DataModel::Nullable<CharSpan>> mDefaultNTP;
     576             :     Optional<app::DataModel::Nullable<app::Clusters::TimeSynchronization::Structs::FabricScopedTrustedTimeSourceStruct::Type>>
     577             :         mTrustedTimeSource;
     578             :     Optional<ByteSpan> mCSRNonce;
     579             :     Optional<ByteSpan> mAttestationNonce;
     580             :     Optional<WiFiCredentials> mWiFiCreds;
     581             :     Optional<CharSpan> mCountryCode;
     582             :     Optional<ByteSpan> mThreadOperationalDataset;
     583             :     Optional<NOCChainGenerationParameters> mNOCChainGenerationParameters;
     584             :     Optional<ByteSpan> mRootCert;
     585             :     Optional<ByteSpan> mNoc;
     586             :     Optional<ByteSpan> mIcac;
     587             :     Optional<IdentityProtectionKey> mIpk;
     588             :     Optional<NodeId> mAdminSubject;
     589             :     // Items that come from the device in commissioning steps
     590             :     Optional<ByteSpan> mAttestationElements;
     591             :     Optional<ByteSpan> mAttestationSignature;
     592             :     Optional<ByteSpan> mPAI;
     593             :     Optional<ByteSpan> mDAC;
     594             :     Optional<NodeId> mRemoteNodeId;
     595             :     Optional<VendorId> mRemoteVendorId;
     596             :     Optional<uint16_t> mRemoteProductId;
     597             :     Optional<app::Clusters::GeneralCommissioning::RegulatoryLocationTypeEnum> mDefaultRegulatoryLocation;
     598             :     Optional<app::Clusters::GeneralCommissioning::RegulatoryLocationTypeEnum> mLocationCapability;
     599             :     Optional<bool> mSupportsConcurrentConnection;
     600             :     CompletionStatus completionStatus;
     601             :     Credentials::DeviceAttestationDelegate * mDeviceAttestationDelegate =
     602             :         nullptr; // Delegate to handle device attestation failures during commissioning
     603             :     Optional<bool> mAttemptWiFiNetworkScan;
     604             :     Optional<bool> mAttemptThreadNetworkScan; // This automatically gets set to false when a ThreadOperationalDataset is set
     605             :     Optional<bool> mSkipCommissioningComplete;
     606             : 
     607             :     Optional<NodeId> mICDCheckInNodeId;
     608             :     Optional<uint64_t> mICDMonitoredSubject;
     609             :     Optional<ByteSpan> mICDSymmetricKey;
     610             : 
     611             :     ICDRegistrationStrategy mICDRegistrationStrategy = ICDRegistrationStrategy::kIgnore;
     612             :     bool mCheckForMatchingFabric                     = false;
     613             : };
     614             : 
     615             : struct RequestedCertificate
     616             : {
     617           0 :     RequestedCertificate(ByteSpan newCertificate) : certificate(newCertificate) {}
     618             :     ByteSpan certificate;
     619             : };
     620             : 
     621             : struct AttestationResponse
     622             : {
     623           0 :     AttestationResponse(ByteSpan newAttestationElements, ByteSpan newSignature) :
     624           0 :         attestationElements(newAttestationElements), signature(newSignature)
     625           0 :     {}
     626             :     ByteSpan attestationElements;
     627             :     ByteSpan signature;
     628             : };
     629             : 
     630             : struct CSRResponse
     631             : {
     632           0 :     CSRResponse(ByteSpan elements, ByteSpan newSignature) : nocsrElements(elements), signature(newSignature) {}
     633             :     ByteSpan nocsrElements;
     634             :     ByteSpan signature;
     635             : };
     636             : 
     637             : struct NocChain
     638             : {
     639           0 :     NocChain(ByteSpan newNoc, ByteSpan newIcac, ByteSpan newRcac, IdentityProtectionKeySpan newIpk, NodeId newAdminSubject) :
     640           0 :         noc(newNoc), icac(newIcac), rcac(newRcac), ipk(newIpk), adminSubject(newAdminSubject)
     641           0 :     {}
     642             :     ByteSpan noc;
     643             :     ByteSpan icac;
     644             :     ByteSpan rcac;
     645             :     IdentityProtectionKeySpan ipk;
     646             :     NodeId adminSubject;
     647             : };
     648             : 
     649             : struct OperationalNodeFoundData
     650             : {
     651           0 :     OperationalNodeFoundData(OperationalDeviceProxy proxy) : operationalProxy(proxy) {}
     652             :     OperationalDeviceProxy operationalProxy;
     653             : };
     654             : 
     655             : struct NetworkClusterInfo
     656             : {
     657             :     EndpointId endpoint = kInvalidEndpointId;
     658             :     app::Clusters::NetworkCommissioning::Attributes::ConnectMaxTimeSeconds::TypeInfo::DecodableType minConnectionTime;
     659             : };
     660             : struct NetworkClusters
     661             : {
     662             :     NetworkClusterInfo wifi;
     663             :     NetworkClusterInfo thread;
     664             :     NetworkClusterInfo eth;
     665             : };
     666             : struct BasicClusterInfo
     667             : {
     668             :     VendorId vendorId  = VendorId::Common;
     669             :     uint16_t productId = 0;
     670             : };
     671             : struct GeneralCommissioningInfo
     672             : {
     673             :     uint64_t breadcrumb          = 0;
     674             :     uint16_t recommendedFailsafe = 0;
     675             :     app::Clusters::GeneralCommissioning::RegulatoryLocationTypeEnum currentRegulatoryLocation =
     676             :         app::Clusters::GeneralCommissioning::RegulatoryLocationTypeEnum::kIndoorOutdoor;
     677             :     app::Clusters::GeneralCommissioning::RegulatoryLocationTypeEnum locationCapability =
     678             :         app::Clusters::GeneralCommissioning::RegulatoryLocationTypeEnum::kIndoorOutdoor;
     679             :     ;
     680             : };
     681             : 
     682             : // ICDManagementClusterInfo is populated when the controller reads information from
     683             : // the ICD Management cluster, and is used to communicate that information.
     684             : struct ICDManagementClusterInfo
     685             : {
     686             :     // Whether the ICD is capable of functioning as a LIT device.  If false, the ICD can only be a SIT device.
     687             :     bool isLIT;
     688             :     // Whether the ICD supports the check-in protocol.  LIT devices have to support it, but SIT devices
     689             :     // might or might not.
     690             :     bool checkInProtocolSupport;
     691             : 
     692             :     // userActiveModeTriggerHint indicates which user action(s) will trigger the ICD to switch to Active mode.
     693             :     // For a LIT: The device is required to provide a value for the bitmap.
     694             :     // For a SIT: The device may not provide a value.  In that case, none of the bits will be set.
     695             :     //
     696             :     // userActiveModeTriggerInstruction may provide additional information for users for some specific
     697             :     // userActiveModeTriggerHint values.
     698             :     BitMask<app::Clusters::IcdManagement::UserActiveModeTriggerBitmap> userActiveModeTriggerHint;
     699             :     CharSpan userActiveModeTriggerInstruction;
     700             : };
     701             : 
     702             : struct ReadCommissioningInfo
     703             : {
     704             :     NetworkClusters network;
     705             :     BasicClusterInfo basic;
     706             :     GeneralCommissioningInfo general;
     707             :     bool requiresUTC                  = false;
     708             :     bool requiresTimeZone             = false;
     709             :     bool requiresDefaultNTP           = false;
     710             :     bool requiresTrustedTimeSource    = false;
     711             :     uint8_t maxTimeZoneSize           = 1;
     712             :     uint8_t maxDSTSize                = 1;
     713             :     NodeId remoteNodeId               = kUndefinedNodeId;
     714             :     bool supportsConcurrentConnection = true;
     715             :     ICDManagementClusterInfo icd;
     716             : };
     717             : 
     718             : struct TimeZoneResponseInfo
     719             : {
     720             :     bool requiresDSTOffsets;
     721             : };
     722             : 
     723             : struct AttestationErrorInfo
     724             : {
     725           0 :     AttestationErrorInfo(Credentials::AttestationVerificationResult result) : attestationResult(result) {}
     726             :     Credentials::AttestationVerificationResult attestationResult;
     727             : };
     728             : 
     729             : struct CommissioningErrorInfo
     730             : {
     731           0 :     CommissioningErrorInfo(app::Clusters::GeneralCommissioning::CommissioningErrorEnum result) : commissioningError(result) {}
     732             :     app::Clusters::GeneralCommissioning::CommissioningErrorEnum commissioningError;
     733             : };
     734             : 
     735             : struct NetworkCommissioningStatusInfo
     736             : {
     737           0 :     NetworkCommissioningStatusInfo(app::Clusters::NetworkCommissioning::NetworkCommissioningStatusEnum result) :
     738           0 :         networkCommissioningStatus(result)
     739           0 :     {}
     740             :     app::Clusters::NetworkCommissioning::NetworkCommissioningStatusEnum networkCommissioningStatus;
     741             : };
     742             : 
     743             : class CommissioningDelegate
     744             : {
     745             : public:
     746           0 :     virtual ~CommissioningDelegate(){};
     747             :     /* CommissioningReport is returned after each commissioning step is completed. The reports for each step are:
     748             :      * kReadCommissioningInfo: Reported together with ReadCommissioningInfo2
     749             :      * kReadCommissioningInfo2: ReadCommissioningInfo
     750             :      * kArmFailsafe: CommissioningErrorInfo if there is an error
     751             :      * kConfigRegulatory: CommissioningErrorInfo if there is an error
     752             :      * kConfigureUTCTime: None
     753             :      * kConfigureTimeZone: TimeZoneResponseInfo
     754             :      * kConfigureDSTOffset: None
     755             :      * kConfigureDefaultNTP: None
     756             :      * kSendPAICertificateRequest: RequestedCertificate
     757             :      * kSendDACCertificateRequest: RequestedCertificate
     758             :      * kSendAttestationRequest: AttestationResponse
     759             :      * kAttestationVerification: AttestationErrorInfo if there is an error
     760             :      * kSendOpCertSigningRequest: CSRResponse
     761             :      * kGenerateNOCChain: NocChain
     762             :      * kSendTrustedRootCert: None
     763             :      * kSendNOC: none
     764             :      * kConfigureTrustedTimeSource: None
     765             :      * kWiFiNetworkSetup: NetworkCommissioningStatusInfo if there is an error
     766             :      * kThreadNetworkSetup: NetworkCommissioningStatusInfo if there is an error
     767             :      * kWiFiNetworkEnable: NetworkCommissioningStatusInfo if there is an error
     768             :      * kThreadNetworkEnable: NetworkCommissioningStatusInfo if there is an error
     769             :      * kFindOperational: OperationalNodeFoundData
     770             :      * kSendComplete: CommissioningErrorInfo if there is an error
     771             :      * kCleanup: none
     772             :      */
     773             :     struct CommissioningReport
     774             :         : Variant<RequestedCertificate, AttestationResponse, CSRResponse, NocChain, OperationalNodeFoundData, ReadCommissioningInfo,
     775             :                   AttestationErrorInfo, CommissioningErrorInfo, NetworkCommissioningStatusInfo, TimeZoneResponseInfo>
     776             :     {
     777           0 :         CommissioningReport() : stageCompleted(CommissioningStage::kError) {}
     778             :         CommissioningStage stageCompleted;
     779             :     };
     780             :     virtual CHIP_ERROR SetCommissioningParameters(const CommissioningParameters & params)                           = 0;
     781             :     virtual const CommissioningParameters & GetCommissioningParameters() const                                      = 0;
     782             :     virtual void SetOperationalCredentialsDelegate(OperationalCredentialsDelegate * operationalCredentialsDelegate) = 0;
     783             :     virtual CHIP_ERROR StartCommissioning(DeviceCommissioner * commissioner, CommissioneeDeviceProxy * proxy)       = 0;
     784             :     virtual CHIP_ERROR CommissioningStepFinished(CHIP_ERROR err, CommissioningReport report)                        = 0;
     785             : };
     786             : 
     787             : } // namespace Controller
     788             : } // namespace chip

Generated by: LCOV version 1.14