LCOV - code coverage report
Current view: top level - app/server - CommissioningWindowManager.h (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 10 13 76.9 %
Date: 2024-02-15 08:20:41 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  *    Copyright (c) 2021-2022 Project CHIP Authors
       4             :  *
       5             :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6             :  *    you may not use this file except in compliance with the License.
       7             :  *    You may obtain a copy of the License at
       8             :  *
       9             :  *        http://www.apache.org/licenses/LICENSE-2.0
      10             :  *
      11             :  *    Unless required by applicable law or agreed to in writing, software
      12             :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13             :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14             :  *    See the License for the specific language governing permissions and
      15             :  *    limitations under the License.
      16             :  */
      17             : 
      18             : #pragma once
      19             : 
      20             : #include <app/data-model/Nullable.h>
      21             : #include <app/server/AppDelegate.h>
      22             : #include <app/server/CommissioningModeProvider.h>
      23             : #include <lib/core/CHIPVendorIdentifiers.hpp>
      24             : #include <lib/core/ClusterEnums.h>
      25             : #include <lib/core/DataModelTypes.h>
      26             : #include <lib/dnssd/Advertiser.h>
      27             : #include <messaging/ExchangeDelegate.h>
      28             : #include <platform/CHIPDeviceConfig.h>
      29             : #include <protocols/secure_channel/RendezvousParameters.h>
      30             : #include <system/SystemClock.h>
      31             : 
      32             : namespace chip {
      33             : 
      34             : enum class CommissioningWindowAdvertisement
      35             : {
      36             :     kAllSupported,
      37             :     kDnssdOnly,
      38             : };
      39             : 
      40             : class Server;
      41             : 
      42             : class CommissioningWindowManager : public Messaging::UnsolicitedMessageHandler,
      43             :                                    public SessionEstablishmentDelegate,
      44             :                                    public app::CommissioningModeProvider,
      45             :                                    public SessionDelegate
      46             : {
      47             : public:
      48           1 :     CommissioningWindowManager() : mPASESession(*this) {}
      49             : 
      50           1 :     CHIP_ERROR Init(Server * server)
      51             :     {
      52           1 :         if (server == nullptr)
      53             :         {
      54           0 :             return CHIP_ERROR_INVALID_ARGUMENT;
      55             :         }
      56           1 :         mServer = server;
      57           1 :         return CHIP_NO_ERROR;
      58             :     }
      59             : 
      60           0 :     static constexpr System::Clock::Seconds16 MaxCommissioningTimeout()
      61             :     {
      62             : #if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING
      63             :         // Specification section 2.3.1 - Extended Announcement Duration up to 48h
      64             :         return System::Clock::Seconds16(60 * 60 * 48);
      65             : #else
      66             :         // Specification section 5.4.2.3. Announcement Duration says 15 minutes.
      67           0 :         return System::Clock::Seconds16(15 * 60);
      68             : #endif
      69             :     }
      70             : 
      71           6 :     System::Clock::Seconds16 MinCommissioningTimeout() const
      72             :     {
      73             :         // Specification section 5.4.2.3. Announcement Duration says 3 minutes.
      74           6 :         return mMinCommissioningTimeoutOverride.ValueOr(System::Clock::Seconds16(3 * 60));
      75             :     }
      76             : 
      77           1 :     void SetAppDelegate(AppDelegate * delegate) { mAppDelegate = delegate; }
      78             : 
      79             :     /**
      80             :      * Open the pairing window using default configured parameters.
      81             :      */
      82             :     CHIP_ERROR
      83             :     OpenBasicCommissioningWindow(
      84           1 :         System::Clock::Seconds16 commissioningTimeout      = System::Clock::Seconds16(CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS),
      85             :         CommissioningWindowAdvertisement advertisementMode = chip::CommissioningWindowAdvertisement::kAllSupported);
      86             : 
      87             :     /**
      88             :      * Open the pairing window using default configured parameters, triggered by
      89             :      * the Administrator Commmissioning cluster implementation.
      90             :      */
      91             :     CHIP_ERROR
      92             :     OpenBasicCommissioningWindowForAdministratorCommissioningCluster(System::Clock::Seconds16 commissioningTimeout,
      93             :                                                                      FabricIndex fabricIndex, VendorId vendorId);
      94             : 
      95             :     CHIP_ERROR OpenEnhancedCommissioningWindow(System::Clock::Seconds16 commissioningTimeout, uint16_t discriminator,
      96             :                                                Spake2pVerifier & verifier, uint32_t iterations, chip::ByteSpan salt,
      97             :                                                FabricIndex fabricIndex, VendorId vendorId);
      98             : 
      99             :     void CloseCommissioningWindow();
     100             : 
     101             :     app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum CommissioningWindowStatusForCluster() const;
     102             : 
     103             :     bool IsCommissioningWindowOpen() const;
     104             : 
     105             :     const app::DataModel::Nullable<VendorId> & GetOpenerVendorId() const { return mOpenerVendorId; }
     106             : 
     107             :     const app::DataModel::Nullable<FabricIndex> & GetOpenerFabricIndex() const { return mOpenerFabricIndex; }
     108             : 
     109             :     void OnFabricRemoved(FabricIndex removedIndex);
     110             : 
     111             :     // CommissioningModeProvider implementation.
     112             :     Dnssd::CommissioningMode GetCommissioningMode() const override;
     113             : 
     114             :     //// UnsolicitedMessageHandler Implementation ////
     115             :     CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader,
     116             :                                             Messaging::ExchangeDelegate *& newDelegate) override;
     117             :     void OnExchangeCreationFailed(Messaging::ExchangeDelegate * delegate) override;
     118             : 
     119             :     //////////// SessionEstablishmentDelegate Implementation ///////////////
     120             :     void OnSessionEstablishmentError(CHIP_ERROR error) override;
     121             :     void OnSessionEstablishmentStarted() override;
     122             :     void OnSessionEstablished(const SessionHandle & session) override;
     123             : 
     124             :     void Shutdown();
     125             : 
     126             :     void OnPlatformEvent(const DeviceLayer::ChipDeviceEvent * event);
     127             : 
     128             :     // For tests only, allow overriding the spec-defined minimum value of the
     129             :     // commissioning window timeout.
     130             :     void OverrideMinCommissioningTimeout(System::Clock::Seconds16 timeout) { mMinCommissioningTimeoutOverride.SetValue(timeout); }
     131             : 
     132             : private:
     133             :     //////////// SessionDelegate Implementation ///////////////
     134             :     void OnSessionReleased() override;
     135             : 
     136           6 :     void SetBLE(bool ble) { mIsBLE = ble; }
     137             : 
     138             :     CHIP_ERROR SetTemporaryDiscriminator(uint16_t discriminator);
     139             : 
     140             :     CHIP_ERROR RestoreDiscriminator();
     141             : 
     142             :     CHIP_ERROR StartAdvertisement();
     143             : 
     144             :     CHIP_ERROR StopAdvertisement(bool aShuttingDown);
     145             : 
     146             :     // Start a timer that will call HandleCommissioningWindowTimeout, and then
     147             :     // start advertising and listen for PASE.
     148             :     CHIP_ERROR OpenCommissioningWindow(System::Clock::Seconds16 commissioningTimeout);
     149             : 
     150             :     // Start advertising and listening for PASE connections.  Should only be
     151             :     // called when a commissioning window timeout timer is running.
     152             :     CHIP_ERROR AdvertiseAndListenForPASE();
     153             : 
     154             :     // Call AdvertiseAndListenForPASE, only if max attempts have not been reached.
     155             :     // Cleans up and calls app server delegate on failure.
     156             :     // err gives the current error we're attemping to recover from
     157             :     void HandleFailedAttempt(CHIP_ERROR err);
     158             : 
     159             :     // Helper for Shutdown and Cleanup.  Does not do anything with
     160             :     // advertisements, because Shutdown and Cleanup want to handle those
     161             :     // differently.
     162             :     void ResetState();
     163             : 
     164             :     void Cleanup();
     165             : 
     166             :     /**
     167             :      * Function that gets called when our commissioning window timeout timer
     168             :      * fires.
     169             :      *
     170             :      * This timer is started when a commissioning window is initially opened via
     171             :      * OpenEnhancedCommissioningWindow or OpenBasicCommissioningWindow.
     172             :      *
     173             :      * The timer is canceled when a PASE connection is established, because it
     174             :      * should not affect the actual commissioning process, and after a PASE
     175             :      * connection is established we will not re-enter commissioning mode without
     176             :      * a new call to OpenEnhancedCommissioningWindow or
     177             :      * OpenBasicCommissioningWindow.
     178             :      */
     179             :     static void HandleCommissioningWindowTimeout(chip::System::Layer * aSystemLayer, void * aAppState);
     180             : 
     181             :     /**
     182             :      * Helper to immediately expire the fail-safe if it's currently armed.
     183             :      */
     184             :     void ExpireFailSafeIfArmed();
     185             : 
     186             :     /**
     187             :      * Helpers to ensure the right attribute reporting happens when our state is
     188             :      * updated.
     189             :      */
     190             :     void UpdateWindowStatus(app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum aNewStatus);
     191             :     void UpdateOpenerVendorId(app::DataModel::Nullable<VendorId> aNewOpenerVendorId);
     192             :     void UpdateOpenerFabricIndex(app::DataModel::Nullable<FabricIndex> aNewOpenerFabricIndex);
     193             : 
     194             :     AppDelegate * mAppDelegate = nullptr;
     195             :     Server * mServer           = nullptr;
     196             : 
     197             :     app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum mWindowStatus =
     198             :         app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen;
     199             : 
     200             :     bool mIsBLE = true;
     201             : 
     202             :     PASESession mPairingSession;
     203             : 
     204             :     uint8_t mFailedCommissioningAttempts = 0;
     205             : 
     206             :     bool mUseECM = false;
     207             :     Spake2pVerifier mECMPASEVerifier;
     208             :     uint16_t mECMDiscriminator = 0;
     209             :     // mListeningForPASE is true only when we are listening for
     210             :     // PBKDFParamRequest messages or when we're in the middle of a PASE
     211             :     // handshake.
     212             :     bool mListeningForPASE = false;
     213             :     // Boolean that tracks whether we have a live commissioning timeout timer.
     214             :     bool mCommissioningTimeoutTimerArmed = false;
     215             :     uint32_t mECMIterations              = 0;
     216             :     uint32_t mECMSaltLength              = 0;
     217             :     uint8_t mECMSalt[kSpake2p_Max_PBKDF_Salt_Length];
     218             : 
     219             :     // For tests only, so that we can test the commissioning window timeout
     220             :     // without having to wait 3 minutes.
     221             :     Optional<System::Clock::Seconds16> mMinCommissioningTimeoutOverride;
     222             : 
     223             :     // The PASE session we are using, so we can handle CloseSession properly.
     224             :     SessionHolderWithDelegate mPASESession;
     225             : 
     226             :     // Information about who opened the commissioning window.  These will only
     227             :     // be non-null if the window was opened via the operational credentials
     228             :     // cluster and the fabric index may be null even then if the fabric has been
     229             :     // removed.
     230             :     app::DataModel::Nullable<VendorId> mOpenerVendorId;
     231             :     app::DataModel::Nullable<FabricIndex> mOpenerFabricIndex;
     232             : };
     233             : 
     234             : } // namespace chip

Generated by: LCOV version 1.14