diff --git a/.gitmodules b/.gitmodules index 03554f83b5aac6..c902899e694f9a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -330,3 +330,7 @@ branch = matter_support platforms = infineon +[submodule "/workspace/connectedhomeip/third_party/googletest/repo"] + path = /workspace/connectedhomeip/third_party/googletest/repo + url = https://github.com/google/googletest.git + branch = v1.14.x diff --git a/.vscode/launch.json b/.vscode/launch.json index afe60953d9f1bd..8924dc0681c1ec 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,22 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { + "name": "Python Debugger: Current File", + "type": "debugpy", + "request": "launch", + "program": "/workspace/scripts/find_public_methods.py", + "console": "integratedTerminal", + "args": [ + "-C", + "out/unified/", + "-c", + "out/unified/compile_commands.json", + "../../src/platform/Linux/KeyValueStoreManagerImpl.cpp", + "KeyValueStoreManager" + ] + }, + { "name": "LLDB Debugger: All Clusters App (chip-all-clusters-app)", "type": "lldb", @@ -69,6 +85,24 @@ "terminal": "console", "stopOnEntry": false }, + { + "name": "LLDB Debugger: Unit Test", + "type": "lldb", // [vadimcn/codelldb](https://github.com/vadimcn/codelldb) + "request": "launch", + "expressions": "native", + "sourceMap": {}, + "relativePathBase": "${workspaceFolder}", + "breakpointMode": "path", + "sourceLanguages": ["cpp"], + "reverseDebugging": true, + "program": "/workspace/connectedhomeip/out/unified/linux_x64_clang/tests/TestCommissionManager", + "args": [], + "cwd": "/workspace/connectedhomeip/out/unified", + "env": {}, + "stdio": [null, null, null], + "terminal": "console", + "stopOnEntry": false + }, { "name": "Attach to running process", "type": "lldb", diff --git a/BUILD.gn b/BUILD.gn index 0992c61b0510c6..3b2c3f6a181736 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -14,6 +14,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") +import("//build_overrides/googletest.gni") import("//build_overrides/mbedtls.gni") import("//build_overrides/nlassert.gni") import("//build_overrides/nlunit_test.gni") diff --git a/build_overrides/googletest.gni b/build_overrides/googletest.gni new file mode 100644 index 00000000000000..a16a342f1de996 --- /dev/null +++ b/build_overrides/googletest.gni @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + # Root directory for googletest. + googletest_root = "//third_party/googletest" +} diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index aec4d4601390e4..167aeaf983037b 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -2171,6 +2171,22 @@ "source": "server", "isIncoming": 0, "isEnabled": 1 + }, + { + "name": "SetTCAcknowledgements", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetTCAcknowledgementsResponse", + "code": 7, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 } ], "attributes": [ @@ -2254,6 +2270,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "TCAcceptedVersion", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TCMinRequiredVersion", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TCAcknowledgements", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "bitmap16", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TCAcknowledgementsRequired", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "true", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -2328,7 +2408,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "1", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/build_overrides/googletest.gni b/examples/build_overrides/googletest.gni new file mode 100644 index 00000000000000..dd7eb268f085ea --- /dev/null +++ b/examples/build_overrides/googletest.gni @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + # Root directory for nlassert. + googletest_root = "//third_party/googletest" +} diff --git a/examples/chip-tool/commands/pairing/PairingCommand.cpp b/examples/chip-tool/commands/pairing/PairingCommand.cpp index ed80bc007df796..359303a83128b5 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.cpp +++ b/examples/chip-tool/commands/pairing/PairingCommand.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -118,6 +118,17 @@ CommissioningParameters PairingCommand::GetCommissioningParameters() params.SetCountryCode(CharSpan::fromCharString(mCountryCode.Value())); } + // mTCAcknowledgements and mTCAcknowledgementVersion are options, but related. When one is missing, default the value to 0, to + // increase the test tools ability to test the applications. + if (mTCAcknowledgements.HasValue() || mTCAcknowledgementVersion.HasValue()) + { + TermsAndConditionsAcknowledgement termsAndConditionsAcknowledgement = { + .acceptedTermsAndConditions = mTCAcknowledgements.ValueOr(0), + .acceptedTermsAndConditionsVersion = mTCAcknowledgementVersion.ValueOr(0), + }; + params.SetTermsAndConditionsAcknowledgement(termsAndConditionsAcknowledgement); + } + // mTimeZoneList is an optional argument managed by TypedComplexArgument mComplex_TimeZones. // Since optional Complex arguments are not currently supported via the class, // we will use mTimeZoneList.data() value to determine if the argument was provided. diff --git a/examples/chip-tool/commands/pairing/PairingCommand.h b/examples/chip-tool/commands/pairing/PairingCommand.h index 0baf70128531b8..467bd9b30c3f57 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.h +++ b/examples/chip-tool/commands/pairing/PairingCommand.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -182,6 +182,14 @@ class PairingCommand : public CHIPCommand, AddArgument("dst-offset", &mComplex_DSTOffsets, "DSTOffset list to use when setting Time Synchronization cluster's DSTOffset attribute", Argument::kOptional); + + AddArgument("tc-acknowledgements", 0, UINT16_MAX, &mTCAcknowledgements, + "Terms and Conditions acknowledgements to use to set the General Commissioning cluster's TC " + "Acknowledgements bit-field"); + + AddArgument("tc-acknowledgements-version", 0, UINT16_MAX, &mTCAcknowledgementVersion, + "Terms and Conditions acknowledgement version to use to set the General Commissioning cluster's TC " + "Acknowledgement version"); } AddArgument("timeout", 0, UINT16_MAX, &mTimeout); @@ -233,6 +241,8 @@ class PairingCommand : public CHIPCommand, chip::Optional mBypassAttestationVerifier; chip::Optional> mCASEAuthTags; chip::Optional mCountryCode; + chip::Optional mTCAcknowledgements; + chip::Optional mTCAcknowledgementVersion; chip::Optional mSkipICDRegistration; chip::Optional mICDCheckInNodeId; chip::Optional mICDSymmetricKey; diff --git a/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp b/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp index 536ac205454862..b248467b8c4404 100644 --- a/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp +++ b/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2021-2024 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -95,9 +96,32 @@ CHIP_ERROR GeneralCommissioningAttrAccess::Read(const ConcreteReadAttributePath case SupportsConcurrentConnection::Id: { return ReadSupportsConcurrentConnection(aEncoder); } - default: { - break; + case TCAcceptedVersion::Id: { + uint16_t tcAcceptedVersion; + EnhancedSetupFlowProvider * const enhancedSetupFlowProvider = Server::GetInstance().GetEnhancedSetupFlowProvider(); + CHIP_ERROR err = enhancedSetupFlowProvider->GetTermsAndConditionsAcceptedAcknowledgementsVersion(tcAcceptedVersion); + return (CHIP_NO_ERROR != err) ? err : aEncoder.Encode(tcAcceptedVersion); + } + case TCMinRequiredVersion::Id: { + uint16_t tcRequiredVersion; + EnhancedSetupFlowProvider * const enhancedSetupFlowProvider = Server::GetInstance().GetEnhancedSetupFlowProvider(); + CHIP_ERROR err = enhancedSetupFlowProvider->GetTermsAndConditionsRequiredAcknowledgementsVersion(tcRequiredVersion); + return (CHIP_NO_ERROR != err) ? err : aEncoder.Encode(tcRequiredVersion); } + case TCAcknowledgements::Id: { + uint16_t tcAcknowledgements; + EnhancedSetupFlowProvider * const enhancedSetupFlowProvider = Server::GetInstance().GetEnhancedSetupFlowProvider(); + CHIP_ERROR err = enhancedSetupFlowProvider->GetTermsAndConditionsAcceptedAcknowledgements(tcAcknowledgements); + return (CHIP_NO_ERROR != err) ? err : aEncoder.Encode(tcAcknowledgements); + } + case TCAcknowledgementsRequired::Id: { + uint16_t tcAcknowledgementsRequired; + EnhancedSetupFlowProvider * const enhancedSetupFlowProvider = Server::GetInstance().GetEnhancedSetupFlowProvider(); + CHIP_ERROR err = enhancedSetupFlowProvider->GetTermsAndConditionsRequiredAcknowledgements(tcAcknowledgementsRequired); + return (CHIP_NO_ERROR != err) ? err : aEncoder.Encode(tcAcknowledgementsRequired); + } + default: + break; } return CHIP_NO_ERROR; } @@ -214,9 +238,10 @@ bool emberAfGeneralCommissioningClusterCommissioningCompleteCallback( { MATTER_TRACE_SCOPE("CommissioningComplete", "GeneralCommissioning"); - DeviceControlServer * devCtrl = &DeviceLayer::DeviceControlServer::DeviceControlSvr(); - auto & failSafe = Server::GetInstance().GetFailSafeContext(); - auto & fabricTable = Server::GetInstance().GetFabricTable(); + EnhancedSetupFlowProvider * const enhancedSetupFlowProvider = Server::GetInstance().GetEnhancedSetupFlowProvider(); + DeviceControlServer * devCtrl = &DeviceLayer::DeviceControlServer::DeviceControlSvr(); + auto & failSafe = Server::GetInstance().GetFailSafeContext(); + auto & fabricTable = Server::GetInstance().GetFabricTable(); ChipLogProgress(FailSafe, "GeneralCommissioning: Received CommissioningComplete"); @@ -239,34 +264,43 @@ bool emberAfGeneralCommissioningClusterCommissioningCompleteCallback( } else { - if (failSafe.NocCommandHasBeenInvoked()) + CHIP_ERROR err; + + if (!enhancedSetupFlowProvider->HasTermsAndConditionsRequiredAcknowledgementsBeenAccepted()) { - CHIP_ERROR err = fabricTable.CommitPendingFabricData(); - if (err != CHIP_NO_ERROR) - { - // No need to revert on error: CommitPendingFabricData always reverts if not fully successful. - ChipLogError(FailSafe, "GeneralCommissioning: Failed to commit pending fabric data: %" CHIP_ERROR_FORMAT, - err.Format()); - } - else + ChipLogError(AppServer, "Required terms and conditions have not been accepted"); + Breadcrumb::Set(commandPath.mEndpointId, 0); + response.errorCode = CommissioningErrorEnum::kRequiredTCNotAccepted; + } + + else if (!enhancedSetupFlowProvider->HasTermsAndConditionsRequiredAcknowledgementsVersionBeenAccepted()) + { + ChipLogError(AppServer, "Minimum terms and conditions version has not been accepted"); + Breadcrumb::Set(commandPath.mEndpointId, 0); + response.errorCode = CommissioningErrorEnum::kTCMinVersionNotMet; + } + + else + { + if (failSafe.NocCommandHasBeenInvoked()) { + err = fabricTable.CommitPendingFabricData(); + CheckSuccess(err, Failure); ChipLogProgress(FailSafe, "GeneralCommissioning: Successfully commited pending fabric data"); } - CheckSuccess(err, Failure); - } - /* - * Pass fabric of commissioner to DeviceControlSvr. - * This allows device to send messages back to commissioner. - * Once bindings are implemented, this may no longer be needed. - */ - failSafe.DisarmFailSafe(); - CheckSuccess( - devCtrl->PostCommissioningCompleteEvent(handle->AsSecureSession()->GetPeerNodeId(), handle->GetFabricIndex()), - Failure); + /* + * Pass fabric of commissioner to DeviceControlSvr. + * This allows device to send messages back to commissioner. + * Once bindings are implemented, this may no longer be needed. + */ + failSafe.DisarmFailSafe(); + err = devCtrl->PostCommissioningCompleteEvent(handle->AsSecureSession()->GetPeerNodeId(), handle->GetFabricIndex()); + CheckSuccess(err, Failure); - Breadcrumb::Set(commandPath.mEndpointId, 0); - response.errorCode = CommissioningErrorEnum::kOk; + Breadcrumb::Set(commandPath.mEndpointId, 0); + response.errorCode = CommissioningErrorEnum::kOk; + } } } @@ -328,13 +362,35 @@ bool emberAfGeneralCommissioningClusterSetRegulatoryConfigCallback(app::CommandH return true; } +bool emberAfGeneralCommissioningClusterSetTCAcknowledgementsCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgements::DecodableType & commandData) +{ + MATTER_TRACE_SCOPE("SetTCAcknowledgements", "GeneralCommissioning"); + Commands::SetTCAcknowledgementsResponse::Type response; + EnhancedSetupFlowProvider * const enhancedSetupFlowProvider = Server::GetInstance().GetEnhancedSetupFlowProvider(); + uint16_t acknowledgements = commandData.TCUserResponse; + uint16_t acknowledgementsVersion = commandData.TCVersion; + CheckSuccess(enhancedSetupFlowProvider->SetTermsAndConditionsAcceptance(acknowledgements, acknowledgementsVersion), Failure); + response.errorCode = CommissioningErrorEnum::kOk; + + commandObj->AddResponse(commandPath, response); + return true; +} + namespace { void OnPlatformEventHandler(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg) { - if (event->Type == DeviceLayer::DeviceEventType::kFailSafeTimerExpired) + switch (event->Type) { + case DeviceLayer::DeviceEventType::kFailSafeTimerExpired: { // Spec says to reset Breadcrumb attribute to 0. Breadcrumb::Set(0, 0); + break; + } + default: { + break; + } } } diff --git a/src/app/server/BUILD.gn b/src/app/server/BUILD.gn index 7c661464bbaea3..6f9998991ac947 100644 --- a/src/app/server/BUILD.gn +++ b/src/app/server/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2020 Project CHIP Authors +# Copyright (c) 2020-2024 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -36,14 +36,20 @@ static_library("server") { "CommissioningWindowManager.h", "DefaultAclStorage.cpp", "DefaultAclStorage.h", + "DefaultEnhancedSetupFlowProvider.cpp", + "DefaultEnhancedSetupFlowProvider.h", + "DefaultTermsAndConditionsProvider.cpp", + "DefaultTermsAndConditionsProvider.h", "Dnssd.cpp", "Dnssd.h", "EchoHandler.cpp", "EchoHandler.h", + "EnhancedSetupFlowProvider.h", "OnboardingCodesUtil.cpp", "OnboardingCodesUtil.h", "Server.cpp", "Server.h", + "TermsAndConditionsProvider.h", ] public_configs = [ ":server_config" ] diff --git a/src/app/server/DefaultEnhancedSetupFlowProvider.cpp b/src/app/server/DefaultEnhancedSetupFlowProvider.cpp new file mode 100644 index 00000000000000..d8c3a8995691f1 --- /dev/null +++ b/src/app/server/DefaultEnhancedSetupFlowProvider.cpp @@ -0,0 +1,104 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "DefaultEnhancedSetupFlowProvider.h" + +#include +#include + +CHIP_ERROR chip::app::DefaultEnhancedSetupFlowProvider::Init(TermsAndConditionsProvider * aTermsAndConditionsProvider) +{ + mTermsAndConditionsProvider = aTermsAndConditionsProvider; + return CHIP_NO_ERROR; +} + +bool chip::app::DefaultEnhancedSetupFlowProvider::HasTermsAndConditionsRequiredAcknowledgementsBeenAccepted() +{ + uint16_t requiredAcknowledgements; + uint16_t requiredAcknowledgementsVersion; + uint16_t acceptedAcknowledgements; + uint16_t acceptedAcknowledgementsVersion; + + mTermsAndConditionsProvider->GetRequirements(requiredAcknowledgements, requiredAcknowledgementsVersion); + mTermsAndConditionsProvider->GetAcceptance(acceptedAcknowledgements, acceptedAcknowledgementsVersion); + + return (requiredAcknowledgements & acceptedAcknowledgements) == requiredAcknowledgements; +} + +bool chip::app::DefaultEnhancedSetupFlowProvider::HasTermsAndConditionsRequiredAcknowledgementsVersionBeenAccepted() +{ + uint16_t requiredAcknowledgements; + uint16_t requiredAcknowledgementsVersion; + uint16_t acceptedAcknowledgements; + uint16_t acceptedAcknowledgementsVersion; + + mTermsAndConditionsProvider->GetRequirements(requiredAcknowledgements, requiredAcknowledgementsVersion); + mTermsAndConditionsProvider->GetAcceptance(acceptedAcknowledgements, acceptedAcknowledgementsVersion); + + return acceptedAcknowledgementsVersion >= requiredAcknowledgementsVersion; +} + +CHIP_ERROR chip::app::DefaultEnhancedSetupFlowProvider::GetTermsAndConditionsRequiredAcknowledgements(uint16_t & value) +{ + uint16_t requiredAcknowledgements; + uint16_t requiredAcknowledgementsVersion; + + mTermsAndConditionsProvider->GetRequirements(requiredAcknowledgements, requiredAcknowledgementsVersion); + + value = requiredAcknowledgements; + return CHIP_NO_ERROR; +} + +CHIP_ERROR chip::app::DefaultEnhancedSetupFlowProvider::GetTermsAndConditionsRequiredAcknowledgementsVersion(uint16_t & value) +{ + uint16_t requiredAcknowledgements; + uint16_t requiredAcknowledgementsVersion; + + mTermsAndConditionsProvider->GetRequirements(requiredAcknowledgements, requiredAcknowledgementsVersion); + + value = requiredAcknowledgementsVersion; + return CHIP_NO_ERROR; +} + +CHIP_ERROR chip::app::DefaultEnhancedSetupFlowProvider::GetTermsAndConditionsAcceptedAcknowledgements(uint16_t & value) +{ + uint16_t acceptedAcknowledgements; + uint16_t acceptedAcknowledgementsVersion; + + mTermsAndConditionsProvider->GetAcceptance(acceptedAcknowledgements, acceptedAcknowledgementsVersion); + + value = acceptedAcknowledgements; + return CHIP_NO_ERROR; +} + +CHIP_ERROR chip::app::DefaultEnhancedSetupFlowProvider::GetTermsAndConditionsAcceptedAcknowledgementsVersion(uint16_t & value) +{ + uint16_t acceptedAcknowledgements; + uint16_t acceptedAcknowledgementsVersion; + + mTermsAndConditionsProvider->GetAcceptance(acceptedAcknowledgements, acceptedAcknowledgementsVersion); + + value = acceptedAcknowledgementsVersion; + return CHIP_NO_ERROR; +} + +CHIP_ERROR chip::app::DefaultEnhancedSetupFlowProvider::SetTermsAndConditionsAcceptance(uint16_t aTCAcknowledgements, + uint16_t aTCAcknowledgementsVersion) +{ + return mTermsAndConditionsProvider->SetAcceptance(aTCAcknowledgements, aTCAcknowledgementsVersion); +} diff --git a/src/app/server/DefaultEnhancedSetupFlowProvider.h b/src/app/server/DefaultEnhancedSetupFlowProvider.h new file mode 100644 index 00000000000000..c053030ad242d2 --- /dev/null +++ b/src/app/server/DefaultEnhancedSetupFlowProvider.h @@ -0,0 +1,101 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "EnhancedSetupFlowProvider.h" + +#include + +#include + +#include "TermsAndConditionsProvider.h" + +namespace chip { +namespace app { +class DefaultEnhancedSetupFlowProvider : public EnhancedSetupFlowProvider +{ +public: + /** + * @brief Initializes the EnhancedSetupFlowProvider. + * + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR Init(TermsAndConditionsProvider * aTermsAndConditionsProvider); + + /** + * @brief Checks if the required terms and conditions acknowledgements have been accepted. + * + * @return true if the required acknowledgements have been accepted, false otherwise. + */ + virtual bool HasTermsAndConditionsRequiredAcknowledgementsBeenAccepted(); + + /** + * @brief Checks if the required terms and conditions acknowledgements version has been accepted. + * + * @return true if the required acknowledgements version has been accepted, false otherwise. + */ + virtual bool HasTermsAndConditionsRequiredAcknowledgementsVersionBeenAccepted(); + + /** + * @brief Retrieves the required terms and conditions acknowledgements. + * + * @param[out] value The value of the required acknowledgements. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR GetTermsAndConditionsRequiredAcknowledgements(uint16_t & value); + + /** + * @brief Retrieves the required terms and conditions acknowledgements version. + * + * @param[out] value The value of the required acknowledgements version. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR GetTermsAndConditionsRequiredAcknowledgementsVersion(uint16_t & value); + + /** + * @brief Retrieves the accepted terms and conditions acknowledgements. + * + * @param[out] value The value of the accepted acknowledgements. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR GetTermsAndConditionsAcceptedAcknowledgements(uint16_t & value); + + /** + * @brief Retrieves the accepted terms and conditions acknowledgements version. + * + * @param[out] value The value of the accepted acknowledgements version. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR GetTermsAndConditionsAcceptedAcknowledgementsVersion(uint16_t & value); + + /** + * @brief Sets the acceptance status of the terms and conditions. + * + * @param[in] aTCAcknowledgements The acknowledgements to accept. + * @param[in] aTCAcknowledgementsVersion The version of the acknowledgements to accept. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR SetTermsAndConditionsAcceptance(uint16_t aTCAcknowledgements, uint16_t aTCAcknowledgementsVersion); + +private: + TermsAndConditionsProvider * mTermsAndConditionsProvider; /**< TermsAndConditionsProvider instance. */ +}; + +}; // namespace app +}; // namespace chip diff --git a/src/app/server/DefaultTermsAndConditionsProvider.cpp b/src/app/server/DefaultTermsAndConditionsProvider.cpp new file mode 100644 index 00000000000000..35446cd932faf3 --- /dev/null +++ b/src/app/server/DefaultTermsAndConditionsProvider.cpp @@ -0,0 +1,61 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "DefaultTermsAndConditionsProvider.h" + +#include +#include + +CHIP_ERROR +chip::app::DefaultTermsAndConditionsProvider::Init(chip::DeviceLayer::PersistedStorage::KeyValueStoreManager * kvsManager) +{ + mKeyValueStoreManager = kvsManager; + return CHIP_NO_ERROR; +} + +CHIP_ERROR chip::app::DefaultTermsAndConditionsProvider::GetAcceptance(uint16_t & aAcknowledgements, + uint16_t & aAcknowledgementsVersion) +{ + uint16_t acknowledgements = 0; + uint16_t acknowledgementsVersion = 0; + + mKeyValueStoreManager->Get(kAcceptedAcknowledgementsKeyName, &acknowledgements, sizeof(acknowledgements)); + mKeyValueStoreManager->Get(kAcceptedAcknowledgementsVersionKeyName, &acknowledgementsVersion, sizeof(acknowledgementsVersion)); + + aAcknowledgements = acknowledgements; + aAcknowledgementsVersion = acknowledgementsVersion; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR chip::app::DefaultTermsAndConditionsProvider::GetRequirements(uint16_t & aAcknowledgements, + uint16_t & aAcknowledgementsVersion) +{ + aAcknowledgements = CHIP_CONFIG_TC_REQUIRED_ACKNOWLEDGEMENTS; + aAcknowledgementsVersion = CHIP_CONFIG_TC_REQUIRED_ACKNOWLEDGEMENTS_VERSION; + return CHIP_NO_ERROR; +} + +CHIP_ERROR chip::app::DefaultTermsAndConditionsProvider::SetAcceptance(uint16_t aAcceptedAcknowledgements, + uint16_t aAcceptedAcknowledgementsVersion) +{ + mKeyValueStoreManager->Put(kAcceptedAcknowledgementsKeyName, &aAcceptedAcknowledgements, sizeof(aAcceptedAcknowledgements)); + mKeyValueStoreManager->Put(kAcceptedAcknowledgementsVersionKeyName, &aAcceptedAcknowledgementsVersion, + sizeof(aAcceptedAcknowledgementsVersion)); + return CHIP_NO_ERROR; +} diff --git a/src/app/server/DefaultTermsAndConditionsProvider.h b/src/app/server/DefaultTermsAndConditionsProvider.h new file mode 100644 index 00000000000000..4d47b342f6829c --- /dev/null +++ b/src/app/server/DefaultTermsAndConditionsProvider.h @@ -0,0 +1,75 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "TermsAndConditionsProvider.h" + +#include + +#include +#include + +namespace chip { +namespace app { +class DefaultTermsAndConditionsProvider : public TermsAndConditionsProvider +{ +public: + static constexpr char kAcceptedAcknowledgementsKeyName[] = "tc-acceptedacknowledgements"; + static constexpr char kAcceptedAcknowledgementsVersionKeyName[] = "tc-acceptedacknowledgementsversion"; + + /** + * @brief Initializes the TermsAndConditionsProvider. + * + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR Init(chip::DeviceLayer::PersistedStorage::KeyValueStoreManager * kvsManager); + + /** + * @brief Retrieves the acceptance status of the required terms and conditions. + * + * @param[out] aAcknowledgements The number of acknowledgements accepted. + * @param[out] aAcknowledgementsVersion The version of the accepted acknowledgements. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR GetAcceptance(uint16_t & aAcknowledgements, uint16_t & aAcknowledgementsVersion); + + /** + * @brief Retrieves the requirements of the terms and conditions. + * + * @param[out] aAcknowledgements The number of required acknowledgements. + * @param[out] aAcknowledgementsVersion The version of the required acknowledgements. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR GetRequirements(uint16_t & aAcknowledgements, uint16_t & aAcknowledgementsVersion); + + /** + * @brief Sets the acceptance status of the required terms and conditions. + * + * @param[in] aAcknowledgements The number of acknowledgements to accept. + * @param[in] aAcknowledgementsVersion The version of the acknowledgements to accept. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR SetAcceptance(uint16_t aAcknowledgements, uint16_t aAcknowledgementsVersion); + +private: + chip::DeviceLayer::PersistedStorage::KeyValueStoreManager * mKeyValueStoreManager; +}; + +}; // namespace app +}; // namespace chip diff --git a/src/app/server/EnhancedSetupFlowProvider.h b/src/app/server/EnhancedSetupFlowProvider.h new file mode 100644 index 00000000000000..729b6577426dbe --- /dev/null +++ b/src/app/server/EnhancedSetupFlowProvider.h @@ -0,0 +1,99 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include +#include + +namespace chip { +namespace app { + +/** + * @brief Feature state access layer for the EnhancedSetupFlowProvider. + * + * This class provides access to the state of the feature through the TermsAndConditionsProvider. + */ +class EnhancedSetupFlowProvider +{ +public: + /** + * @brief Destructor. + */ + virtual ~EnhancedSetupFlowProvider() = default; + + /** + * @brief Checks if the required terms and conditions acknowledgements have been accepted. + * + * @return true if the required acknowledgements have been accepted, false otherwise. + */ + virtual bool HasTermsAndConditionsRequiredAcknowledgementsBeenAccepted() = 0; + + /** + * @brief Checks if the required terms and conditions acknowledgements version has been accepted. + * + * @return true if the required acknowledgements version has been accepted, false otherwise. + */ + virtual bool HasTermsAndConditionsRequiredAcknowledgementsVersionBeenAccepted() = 0; + + /** + * @brief Retrieves the required terms and conditions acknowledgements. + * + * @param[out] value The value of the required acknowledgements. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR GetTermsAndConditionsRequiredAcknowledgements(uint16_t & value) = 0; + + /** + * @brief Retrieves the required terms and conditions acknowledgements version. + * + * @param[out] value The value of the required acknowledgements version. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR GetTermsAndConditionsRequiredAcknowledgementsVersion(uint16_t & value) = 0; + + /** + * @brief Retrieves the accepted terms and conditions acknowledgements. + * + * @param[out] value The value of the accepted acknowledgements. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR GetTermsAndConditionsAcceptedAcknowledgements(uint16_t & value) = 0; + + /** + * @brief Retrieves the accepted terms and conditions acknowledgements version. + * + * @param[out] value The value of the accepted acknowledgements version. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR GetTermsAndConditionsAcceptedAcknowledgementsVersion(uint16_t & value) = 0; + + /** + * @brief Sets the acceptance status of the terms and conditions. + * + * @param[in] aTCAcknowledgements The acknowledgements to accept. + * @param[in] aTCAcknowledgementsVersion The version of the acknowledgements to accept. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR SetTermsAndConditionsAcceptance(uint16_t aTCAcknowledgements, uint16_t aTCAcknowledgementsVersion) = 0; +}; + +}; // namespace app +}; // namespace chip diff --git a/src/app/server/Server.cpp b/src/app/server/Server.cpp index d2983636450691..333867f5f55b2c 100644 --- a/src/app/server/Server.cpp +++ b/src/app/server/Server.cpp @@ -21,6 +21,8 @@ #include #include +#include +#include #include #include #include @@ -122,6 +124,8 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams) VerifyOrExit(initParams.operationalKeystore != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); VerifyOrExit(initParams.opCertStore != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); VerifyOrExit(initParams.reportScheduler != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(initParams.enhancedSetupFlowProvider != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(initParams.termsAndConditionsProvider != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); // TODO(16969): Remove chip::Platform::MemoryInit() call from Server class, it belongs to outer code chip::Platform::MemoryInit(); @@ -178,6 +182,9 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams) mReportScheduler = initParams.reportScheduler; + mTermsAndConditionsProvider = initParams.termsAndConditionsProvider; + mEnhancedSetupFlowProvider = initParams.enhancedSetupFlowProvider; + mTestEventTriggerDelegate = initParams.testEventTriggerDelegate; deviceInfoprovider = DeviceLayer::GetDeviceInfoProvider(); @@ -711,5 +718,7 @@ app::SimpleSubscriptionResumptionStorage CommonCaseDeviceServerInitParams::sSubs #endif app::DefaultAclStorage CommonCaseDeviceServerInitParams::sAclStorage; Crypto::DefaultSessionKeystore CommonCaseDeviceServerInitParams::sSessionKeystore; +app::DefaultEnhancedSetupFlowProvider CommonCaseDeviceServerInitParams::sDefaultEnhancedSetupFlowProvider; +app::DefaultTermsAndConditionsProvider CommonCaseDeviceServerInitParams::sDefaultTermsAndConditionsProvider; } // namespace chip diff --git a/src/app/server/Server.h b/src/app/server/Server.h index 302471b8bebb89..1def576da9a39c 100644 --- a/src/app/server/Server.h +++ b/src/app/server/Server.h @@ -33,6 +33,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -153,7 +157,9 @@ struct ServerInitParams // must not be null at timne of Server::Init(). Credentials::OperationalCertificateStore * opCertStore = nullptr; // Required, if not provided, the Server::Init() WILL fail. - app::reporting::ReportScheduler * reportScheduler = nullptr; + app::reporting::ReportScheduler * reportScheduler = nullptr; + app::EnhancedSetupFlowProvider * enhancedSetupFlowProvider = nullptr; + app::TermsAndConditionsProvider * termsAndConditionsProvider = nullptr; }; /** @@ -202,11 +208,11 @@ struct CommonCaseDeviceServerInitParams : public ServerInitParams */ CHIP_ERROR InitializeStaticResourcesBeforeServerInit() { + chip::DeviceLayer::PersistedStorage::KeyValueStoreManager & kvsManager = DeviceLayer::PersistedStorage::KeyValueStoreMgr(); + // KVS-based persistent storage delegate injection if (persistentStorageDelegate == nullptr) { - chip::DeviceLayer::PersistedStorage::KeyValueStoreManager & kvsManager = - DeviceLayer::PersistedStorage::KeyValueStoreMgr(); ReturnErrorOnFailure(sKvsPersistenStorageDelegate.Init(&kvsManager)); this->persistentStorageDelegate = &sKvsPersistenStorageDelegate; } @@ -238,6 +244,18 @@ struct CommonCaseDeviceServerInitParams : public ServerInitParams reportScheduler = &sReportScheduler; } + if (this->termsAndConditionsProvider == nullptr) + { + ReturnErrorOnFailure(sDefaultTermsAndConditionsProvider.Init(&kvsManager)); + this->termsAndConditionsProvider = &sDefaultTermsAndConditionsProvider; + } + + if (this->enhancedSetupFlowProvider == nullptr) + { + ReturnErrorOnFailure(sDefaultEnhancedSetupFlowProvider.Init(this->termsAndConditionsProvider)); + this->enhancedSetupFlowProvider = &sDefaultEnhancedSetupFlowProvider; + } + // Session Keystore injection this->sessionKeystore = &sSessionKeystore; @@ -287,6 +305,8 @@ struct CommonCaseDeviceServerInitParams : public ServerInitParams #endif static app::DefaultAclStorage sAclStorage; static Crypto::DefaultSessionKeystore sSessionKeystore; + static app::DefaultEnhancedSetupFlowProvider sDefaultEnhancedSetupFlowProvider; + static app::DefaultTermsAndConditionsProvider sDefaultTermsAndConditionsProvider; }; /** @@ -367,6 +387,8 @@ class Server app::reporting::ReportScheduler * GetReportScheduler() { return mReportScheduler; } + app::EnhancedSetupFlowProvider * GetEnhancedSetupFlowProvider() { return mEnhancedSetupFlowProvider; } + #if CHIP_CONFIG_ENABLE_ICD_SERVER app::ICDManager & GetICDManager() { return mICDManager; } #endif // CHIP_CONFIG_ENABLE_ICD_SERVER @@ -628,6 +650,8 @@ class Server GroupDataProviderListener mListener; ServerFabricDelegate mFabricDelegate; app::reporting::ReportScheduler * mReportScheduler; + app::EnhancedSetupFlowProvider * mEnhancedSetupFlowProvider; + app::TermsAndConditionsProvider * mTermsAndConditionsProvider; Access::AccessControl mAccessControl; app::AclStorage * mAclStorage; diff --git a/src/app/server/TermsAndConditionsProvider.h b/src/app/server/TermsAndConditionsProvider.h new file mode 100644 index 00000000000000..9c68fee9e3787e --- /dev/null +++ b/src/app/server/TermsAndConditionsProvider.h @@ -0,0 +1,68 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include + +namespace chip { +namespace app { + +/** + * @brief Data access layer for the required terms and conditions and the store for the user acceptance. + */ +class TermsAndConditionsProvider +{ +public: + /** + * @brief Destructor. + */ + virtual ~TermsAndConditionsProvider() = default; + + /** + * @brief Retrieves the acceptance status of the required terms and conditions. + * + * @param[out] aAcknowledgements The number of acknowledgements accepted. + * @param[out] aAcknowledgementsVersion The version of the accepted acknowledgements. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR GetAcceptance(uint16_t & aAcknowledgements, uint16_t & aAcknowledgementsVersion) = 0; + + /** + * @brief Retrieves the requirements of the terms and conditions. + * + * @param[out] aAcknowledgements The number of required acknowledgements. + * @param[out] aAcknowledgementsVersion The version of the required acknowledgements. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR GetRequirements(uint16_t & aAcknowledgements, uint16_t & aAcknowledgementsVersion) = 0; + + /** + * @brief Sets the acceptance status of the required terms and conditions. + * + * @param[in] aAcknowledgements The number of acknowledgements to accept. + * @param[in] aAcknowledgementsVersion The version of the acknowledgements to accept. + * @return CHIP_ERROR On success returns CHIP_NO_ERROR, otherwise returns an error code. + */ + virtual CHIP_ERROR SetAcceptance(uint16_t aAcknowledgements, uint16_t aAcknowledgementsVersion) = 0; +}; + +}; // namespace app +}; // namespace chip diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn index 78b9c8f69e87df..9cbbdffd5c9e21 100644 --- a/src/app/tests/BUILD.gn +++ b/src/app/tests/BUILD.gn @@ -14,6 +14,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") +import("//build_overrides/googletest.gni") import("//build_overrides/nlunit_test.gni") import("${chip_root}/build/chip/chip_test_suite.gni") @@ -138,7 +139,9 @@ chip_test_suite_using_nltest("tests") { "TestCommandPathParams.cpp", "TestConcreteAttributePath.cpp", "TestDataModelSerialization.cpp", + "TestDefaultEnhancedSetupFlowProvider.cpp", "TestDefaultOTARequestorStorage.cpp", + "TestDefaultTermsAndConditionsProvider.cpp", "TestEventLoggingNoUTCTime.cpp", "TestEventOverflow.cpp", "TestEventPathParams.cpp", @@ -216,6 +219,7 @@ chip_test_suite_using_nltest("tests") { "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/lib/support:testing", "${chip_root}/src/lib/support:testing_nlunit", + "${googletest_root}:googlemock", "${nlunit_test_root}:nlunit-test", ] diff --git a/src/app/tests/TestDefaultEnhancedSetupFlowProvider.cpp b/src/app/tests/TestDefaultEnhancedSetupFlowProvider.cpp new file mode 100644 index 00000000000000..7cf55aec4bd738 --- /dev/null +++ b/src/app/tests/TestDefaultEnhancedSetupFlowProvider.cpp @@ -0,0 +1,67 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +static int Setup(void * inContext) +{ + return SUCCESS; +} + +static int TearDown(void * inContext) +{ + return SUCCESS; +} + +static int Initialize(void * inContext) +{ + return SUCCESS; +} + +static int Terminate(void * inContext) +{ + return SUCCESS; +} + +static void TestDefaultEnhancedSetupFlowProvider(struct _nlTestSuite * inSuite, void * inContext) +{ + NL_TEST_ASSERT(inSuite, true); +} + +static nlTestSuite sEnhancedSetupFlowProviderTestSuite = { + .name = (const char *) "Enhanced Setup Flow Provider Test Suite", + .tests = + (const nlTest[]){ + NL_TEST_DEF("Enhanced Setup Flow Provider Test", TestDefaultEnhancedSetupFlowProvider), + NL_TEST_SENTINEL(), + }, + .setup = (int (*)(void *)) Setup, + .tear_down = (int (*)(void *)) TearDown, + .initialize = (int (*)(void *)) Initialize, + .terminate = (int (*)(void *)) Terminate, +}; + +int TestDefaultEnhancedSetupFlowProvider() +{ + nlTestRunner(&sEnhancedSetupFlowProviderTestSuite, nullptr); + return nlTestRunnerStats(&sEnhancedSetupFlowProviderTestSuite); +} + +CHIP_REGISTER_TEST_SUITE(TestDefaultEnhancedSetupFlowProvider) diff --git a/src/app/tests/TestDefaultTermsAndConditionsProvider.cpp b/src/app/tests/TestDefaultTermsAndConditionsProvider.cpp new file mode 100644 index 00000000000000..a3b26efb16b6a2 --- /dev/null +++ b/src/app/tests/TestDefaultTermsAndConditionsProvider.cpp @@ -0,0 +1,365 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#include "app/server/DefaultTermsAndConditionsProvider.h" +#include "lib/core/CHIPError.h" + +/** + * @brief A struct template representing an action to save a value into a buffer at a specified index. + * + * This struct template is intended for use with Google Mock to define actions for mocked methods. + * It copies a value into a buffer at a specified index when the action is invoked. + * + * @tparam N The index of the argument in the function call arguments tuple. + * @tparam T The type of the value to save into the buffer. + */ +template +struct SaveArgVoidPointeeAction +{ + T value; /**< The value to save into the buffer. */ + + /** + * @brief The function call operator. + * + * This operator is invoked when the action is called. + * It copies the value stored in 'value' into the buffer at the specified index 'N'. + * + * @tparam Args The types of the function call arguments. + * @param args The function call arguments. + */ + template + void operator()(const Args &... args) const + { + // Get the buffer at index 'N' from the tuple of arguments + void * buffer = std::get(std::tie(args...)); + // Copy the value into the buffer + memcpy(buffer, &value, sizeof(value)); + } +}; + +/** + * @brief Helper function to create a SaveArgVoidPointeeAction object. + * + * This function simplifies the creation of SaveArgVoidPointeeAction objects. + * + * @tparam N The index of the argument in the function call arguments tuple. + * @tparam T The type of the value to save into the buffer. + * @param value The value to save into the buffer. + * @return A SaveArgVoidPointeeAction object initialized with the specified value. + */ +template +SaveArgVoidPointeeAction SaveArgVoidPointee(T value) +{ + return { std::move(value) }; +} + +/** + * @brief A mock class for the KeyValueStoreManager interface. + * + * This mock class is used for testing purposes to mock the behavior of the KeyValueStoreManager class. + * It inherits from the KeyValueStoreManager class and provides mock implementations for its methods. + */ +class MockKeyValueStoreManager : public chip::DeviceLayer::PersistedStorage::KeyValueStoreManager +{ +public: + /** + * @brief Mock method for the Get method of KeyValueStoreManager. + * + * This mock method is used to simulate the behavior of the Get method of KeyValueStoreManager. + * It takes parameters similar to the Get method and returns a CHIP_ERROR. + * + * @param key The key to retrieve from the key-value store. + * @param buffer Pointer to the buffer where the retrieved value will be stored. + * @param buffer_size Size of the buffer. + * @param read_bytes_size Pointer to a variable where the number of bytes read will be stored. + * @param offset_bytes Offset within the value from where to start reading. + * @return CHIP_ERROR representing the success or failure of the operation. + */ + MOCK_METHOD5(GetMock, CHIP_ERROR(const char *, void *, size_t, size_t *, size_t)); + + /** + * @brief Mock method for the Put method of KeyValueStoreManager. + * + * This mock method is used to simulate the behavior of the Put method of KeyValueStoreManager. + * It takes parameters similar to the Put method and returns a CHIP_ERROR. + * + * @param key The key under which to store the value in the key-value store. + * @param value Pointer to the value to be stored. + * @param value_size Size of the value. + * @return CHIP_ERROR representing the success or failure of the operation. + */ + MOCK_METHOD3(PutMock, CHIP_ERROR(const char *, const void *, size_t)); + + /** + * @brief Mock method for the Delete method of KeyValueStoreManager. + * + * This mock method is used to simulate the behavior of the Delete method of KeyValueStoreManager. + * It takes a key as a parameter and returns a CHIP_ERROR. + * + * @param key The key to delete from the key-value store. + * @return CHIP_ERROR representing the success or failure of the operation. + */ + MOCK_METHOD1(DeleteMock, CHIP_ERROR(const char *)); + + /** + * @brief Override of the Get method of KeyValueStoreManager. + * + * This method overrides the Get method of KeyValueStoreManager. + * It delegates the call to the corresponding mock method GetMock. + * + * @param key The key to retrieve from the key-value store. + * @param buffer Pointer to the buffer where the retrieved value will be stored. + * @param buffer_size Size of the buffer. + * @param read_bytes_size Pointer to a variable where the number of bytes read will be stored. + * @param offset_bytes Offset within the value from where to start reading. + * @return CHIP_ERROR representing the success or failure of the operation. + */ + CHIP_ERROR Get(const char * key, void * buffer, size_t buffer_size, size_t * read_bytes_size, size_t offset_bytes) + { + return GetMock(key, buffer, buffer_size, read_bytes_size, offset_bytes); + } + + /** + * @brief Override of the Put method of KeyValueStoreManager. + * + * This method overrides the Put method of KeyValueStoreManager. + * It delegates the call to the corresponding mock method PutMock. + * + * @param key The key under which to store the value in the key-value store. + * @param value Pointer to the value to be stored. + * @param value_size Size of the value. + * @return CHIP_ERROR representing the success or failure of the operation. + */ + CHIP_ERROR Put(const char * key, const void * value, size_t value_size) { return PutMock(key, value, value_size); } + + /** + * @brief Override of the Delete method of KeyValueStoreManager. + * + * This method overrides the Delete method of KeyValueStoreManager. + * It delegates the call to the corresponding mock method DeleteMock. + * + * @param key The key to delete from the key-value store. + * @return CHIP_ERROR representing the success or failure of the operation. + */ + CHIP_ERROR Delete(const char * key) { return DeleteMock(key); } +}; + +/** + * @brief Setup function for the test suite. + * + * This function is called before running the test suite. + * It performs any necessary setup steps. + * + * @param inContext A pointer to the context (not used in this function). + * @return SUCCESS if setup succeeds, an error code otherwise. + */ +static int Setup(void * inContext) +{ + return SUCCESS; +} + +/** + * @brief Tear down function for the test suite. + * + * This function is called after running the test suite. + * It performs any necessary cleanup steps. + * + * @param inContext A pointer to the context (not used in this function). + * @return SUCCESS if teardown succeeds, an error code otherwise. + */ +static int TearDown(void * inContext) +{ + return SUCCESS; +} + +/** + * @brief Initialization function for the test suite. + * + * This function is called before running each test case. + * It performs any necessary initialization steps. + * + * @param inContext A pointer to the context (not used in this function). + * @return SUCCESS if initialization succeeds, an error code otherwise. + */ +static int Initialize(void * inContext) +{ + return SUCCESS; +} + +/** + * @brief Termination function for the test suite. + * + * This function is called after running each test case. + * It performs any necessary termination steps. + * + * @param inContext A pointer to the context (not used in this function). + * @return SUCCESS if termination succeeds, an error code otherwise. + */ +static int Terminate(void * inContext) +{ + return SUCCESS; +} + +/** + * @brief Test case for initializing the DefaultTermsAndConditionsProvider. + * + * This test case verifies that the DefaultTermsAndConditionsProvider initializes successfully. + * It initializes the provider with a mock key-value store manager and checks for success. + */ +static void TestDefaultTermsAndConditionsProviderInitSuccess(struct _nlTestSuite * inSuite, void * inContext) +{ + MockKeyValueStoreManager mockKeyValueStoreManager; + + chip::app::DefaultTermsAndConditionsProvider uut; + CHIP_ERROR err = uut.Init(&mockKeyValueStoreManager); + + NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == err); +} + +/** + * @brief Test case for retrieving acceptance from the DefaultTermsAndConditionsProvider. + * + * This test case verifies that the DefaultTermsAndConditionsProvider retrieves acceptance successfully. + * It initializes the provider with a mock key-value store manager, sets up expectations for Get method calls, + * calls the GetAcceptance method, and checks for expected values. + */ +static void TestDefaultTermsAndConditionsProviderGetAcceptanceSuccess(struct _nlTestSuite * inSuite, void * inContext) +{ + CHIP_ERROR err; + uint16_t acknowledgements; + uint16_t acknowledgementsVersion; + + MockKeyValueStoreManager mockKeyValueStoreManager; + chip::app::DefaultTermsAndConditionsProvider uut; + + err = uut.Init(&mockKeyValueStoreManager); + NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == err); + + EXPECT_CALL(mockKeyValueStoreManager, + GetMock(chip::app::DefaultTermsAndConditionsProvider::kAcceptedAcknowledgementsKeyName, testing::_, + sizeof(uint16_t), testing::_, testing::_)) + .WillOnce(testing::DoAll(SaveArgVoidPointee<1>(static_cast(1)), testing::Return(CHIP_NO_ERROR))); + + EXPECT_CALL(mockKeyValueStoreManager, + GetMock(chip::app::DefaultTermsAndConditionsProvider::kAcceptedAcknowledgementsVersionKeyName, testing::_, + sizeof(uint16_t), testing::_, testing::_)) + .WillOnce(testing::DoAll(SaveArgVoidPointee<1>(static_cast(1)), testing::Return(CHIP_NO_ERROR))); + + err = uut.GetAcceptance(acknowledgements, acknowledgementsVersion); + NL_TEST_ASSERT(inSuite, 1 == acknowledgements); + NL_TEST_ASSERT(inSuite, 1 == acknowledgementsVersion); +} + +/** + * @brief Test case for getting requirements from the DefaultTermsAndConditionsProvider. + * + * This test case verifies that getting requirements from the DefaultTermsAndConditionsProvider succeeds. + * It checks for successful execution without any assertions. + */ +static void TestGetRequirementsSuccess(struct _nlTestSuite * inSuite, void * inContext) +{ + // Test implementation goes here... +} + +/** + * @brief Test case for setting acceptance in the DefaultTermsAndConditionsProvider. + * + * This test case verifies that setting acceptance in the DefaultTermsAndConditionsProvider succeeds. + * It checks for successful execution without any assertions. + */ +static void TestSetAcceptanceSuccess(struct _nlTestSuite * inSuite, void * inContext) +{ + // Test implementation goes here... +} + +/** + * @brief Test case for initialization failure of the DefaultTermsAndConditionsProvider. + * + * This test case verifies that the DefaultTermsAndConditionsProvider fails to initialize. + * It checks for failure conditions without any assertions. + */ +static void TestInitFailure(struct _nlTestSuite * inSuite, void * inContext) +{ + // Test implementation goes here... +} + +/** + * @brief Test case for failure in retrieving acceptance from the DefaultTermsAndConditionsProvider. + * + * This test case verifies that retrieving acceptance from the DefaultTermsAndConditionsProvider fails. + * It checks for failure conditions without any assertions. + */ +static void TestGetAcceptanceFailure(struct _nlTestSuite * inSuite, void * inContext) +{ + // Test implementation goes here... +} + +/** + * @brief Test case for failure in getting requirements from the DefaultTermsAndConditionsProvider. + * + * This test case verifies that getting requirements from the DefaultTermsAndConditionsProvider fails. + * It checks for failure conditions without any assertions. + */ +static void TestGetRequirementsFailure(struct _nlTestSuite * inSuite, void * inContext) +{ + // Test implementation goes here... +} + +/** + * @brief Test case for failure in setting acceptance in the DefaultTermsAndConditionsProvider. + * + * This test case verifies that setting acceptance in the DefaultTermsAndConditionsProvider fails. + * It checks for failure conditions without any assertions. + */ +static void TestSetAcceptanceFailure(struct _nlTestSuite * inSuite, void * inContext) +{ + // Test implementation goes here... +} + +static nlTestSuite sDefaultTermsAndConditionsProviderTestSuite = { + .name = (const char *) "Terms and Conditions Provider Test Suite", + .tests = + (const nlTest[]){ + NL_TEST_DEF("TestInitSuccess", TestDefaultTermsAndConditionsProviderInitSuccess), + NL_TEST_DEF("TestGetAcceptanceSuccess", TestDefaultTermsAndConditionsProviderGetAcceptanceSuccess), + NL_TEST_DEF("TestGetRequirementsSuccess", TestGetRequirementsSuccess), + NL_TEST_DEF("TestSetAcceptanceSuccess", TestSetAcceptanceSuccess), + NL_TEST_DEF("TestInitFailure", TestInitFailure), + NL_TEST_DEF("TestGetAcceptanceFailure", TestGetAcceptanceFailure), + NL_TEST_DEF("TestGetRequirementsFailure", TestGetRequirementsFailure), + NL_TEST_DEF("TestSetAcceptanceFailure", TestSetAcceptanceFailure), + NL_TEST_SENTINEL(), + }, + .setup = (int (*)(void *)) Setup, + .tear_down = (int (*)(void *)) TearDown, + .initialize = (int (*)(void *)) Initialize, + .terminate = (int (*)(void *)) Terminate, +}; + +int TestDefaultTermsAndConditionsProvider() +{ + nlTestRunner(&sDefaultTermsAndConditionsProviderTestSuite, nullptr); + return nlTestRunnerStats(&sDefaultTermsAndConditionsProviderTestSuite); +} + +CHIP_REGISTER_TEST_SUITE(TestDefaultTermsAndConditionsProvider) diff --git a/src/controller/AutoCommissioner.cpp b/src/controller/AutoCommissioner.cpp index 42b39a10c7ab48..d64f3c04bb6222 100644 --- a/src/controller/AutoCommissioner.cpp +++ b/src/controller/AutoCommissioner.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2021-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -343,13 +343,25 @@ CommissioningStage AutoCommissioner::GetNextCommissioningStageInternal(Commissio case CommissioningStage::kArmFailsafe: return CommissioningStage::kConfigRegulatory; case CommissioningStage::kConfigRegulatory: + if (mParams.GetTermsAndConditionsAcknowledgement().HasValue()) + { + return CommissioningStage::kConfigureTCAcknowledgments; + } + else if (mDeviceCommissioningInfo.requiresUTC) + { + return CommissioningStage::kConfigureUTCTime; + } + else + { + return CommissioningStage::kSendPAICertificateRequest; + } + case CommissioningStage::kConfigureTCAcknowledgments: if (mDeviceCommissioningInfo.requiresUTC) { return CommissioningStage::kConfigureUTCTime; } else { - // Time cluster is not supported, move right to DA return CommissioningStage::kSendPAICertificateRequest; } case CommissioningStage::kConfigureUTCTime: diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index af0a66ea834da3..8152c12f9c6e8f 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright (c) 2020-2024 Project CHIP Authors * Copyright (c) 2013-2017 Nest Labs, Inc. * All rights reserved. * @@ -2426,6 +2426,22 @@ void DeviceCommissioner::OnSetRegulatoryConfigResponse( commissioner->CommissioningStageComplete(err, report); } +void DeviceCommissioner::OnSetTCAcknowledgementsResponse( + void * context, const GeneralCommissioning::Commands::SetTCAcknowledgementsResponse::DecodableType & data) +{ + CommissioningDelegate::CommissioningReport report; + CHIP_ERROR err = CHIP_NO_ERROR; + + ChipLogProgress(Controller, "Received SetTCAcknowledgements response errorCode=%u", to_underlying(data.errorCode)); + if (data.errorCode != GeneralCommissioning::CommissioningErrorEnum::kOk) + { + err = CHIP_ERROR_INTERNAL; + report.Set(data.errorCode); + } + DeviceCommissioner * commissioner = static_cast(context); + commissioner->CommissioningStageComplete(err, report); +} + void DeviceCommissioner::OnSetTimeZoneResponse(void * context, const TimeSynchronization::Commands::SetTimeZoneResponse::DecodableType & data) { @@ -2874,6 +2890,24 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio } } break; + case CommissioningStage::kConfigureTCAcknowledgments: { + ChipLogProgress(Controller, "Setting Terms and Conditions"); + + GeneralCommissioning::Commands::SetTCAcknowledgements::Type request; + TermsAndConditionsAcknowledgement termsAndConditionsAcknowledgement = params.GetTermsAndConditionsAcknowledgement().Value(); + request.TCUserResponse = termsAndConditionsAcknowledgement.acceptedTermsAndConditions; + request.TCVersion = termsAndConditionsAcknowledgement.acceptedTermsAndConditionsVersion; + CHIP_ERROR err = + SendCommissioningCommand(proxy, request, OnSetTCAcknowledgementsResponse, OnBasicFailure, endpoint, timeout); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Failed to send SetTCAcknowledgements command: %" CHIP_ERROR_FORMAT, err.Format()); + CommissioningStageComplete(err); + return; + } + + break; + } case CommissioningStage::kSendPAICertificateRequest: { ChipLogProgress(Controller, "Sending request for PAI certificate"); CHIP_ERROR err = SendCertificateChainRequestCommand(proxy, CertificateType::kPAI, timeout); diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index dd7b5bc31eec46..d6effac7ad4434 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright (c) 2020-2024 Project CHIP Authors * Copyright (c) 2013-2017 Nest Labs, Inc. * All rights reserved. * @@ -893,6 +893,9 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, static void OnSetRegulatoryConfigResponse( void * context, const chip::app::Clusters::GeneralCommissioning::Commands::SetRegulatoryConfigResponse::DecodableType & data); + static void OnSetTCAcknowledgementsResponse( + void * context, + const chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgementsResponse::DecodableType & data); static void OnSetUTCError(void * context, CHIP_ERROR error); static void OnSetTimeZoneResponse(void * context, diff --git a/src/controller/CommissioningDelegate.h b/src/controller/CommissioningDelegate.h index 4b1040fcd79690..c6d69dd689eebf 100644 --- a/src/controller/CommissioningDelegate.h +++ b/src/controller/CommissioningDelegate.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2021-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,6 +23,7 @@ #include #include #include +#include #include namespace chip { @@ -38,6 +39,7 @@ enum CommissioningStage : uint8_t kReadCommissioningInfo2, ///< Query SupportsConcurrentConnection, ICD state, check for matching fabric kArmFailsafe, ///< Send ArmFailSafe (0x30:0) command to the device kConfigRegulatory, ///< Send SetRegulatoryConfig (0x30:2) command to the device + kConfigureTCAcknowledgments, ///< Send SetTCAcknowledgements (0x30:6) command to the device kConfigureUTCTime, ///< SetUTCTime if the DUT has a time cluster kConfigureTimeZone, ///< Configure a time zone if one is required and available kConfigureDSTOffset, ///< Configure DST offset if one is required and available @@ -94,6 +96,12 @@ struct WiFiCredentials WiFiCredentials(ByteSpan newSsid, ByteSpan newCreds) : ssid(newSsid), credentials(newCreds) {} }; +struct TermsAndConditionsAcknowledgement +{ + uint16_t acceptedTermsAndConditions; + uint16_t acceptedTermsAndConditionsVersion; +}; + struct NOCChainGenerationParameters { ByteSpan nocsrElements; @@ -158,6 +166,11 @@ class CommissioningParameters // The country code to be used for the node, if set. Optional GetCountryCode() const { return mCountryCode; } + Optional GetTermsAndConditionsAcknowledgement() const + { + return mTermsAndConditionsAcknowledgement; + } + // Time zone to set for the node // If required, this will be truncated to fit the max size allowable on the node Optional> GetTimeZone() const @@ -330,6 +343,13 @@ class CommissioningParameters return *this; } + CommissioningParameters & + SetTermsAndConditionsAcknowledgement(TermsAndConditionsAcknowledgement termsAndConditionsAcknowledgement) + { + mTermsAndConditionsAcknowledgement.SetValue(termsAndConditionsAcknowledgement); + return *this; + } + // The lifetime of the list buffer needs to exceed the lifetime of the CommissioningParameters object. CommissioningParameters & SetTimeZone(app::DataModel::List timeZone) @@ -594,6 +614,7 @@ class CommissioningParameters Optional mAttestationNonce; Optional mWiFiCreds; Optional mCountryCode; + Optional mTermsAndConditionsAcknowledgement; Optional mThreadOperationalDataset; Optional mNOCChainGenerationParameters; Optional mRootCert; diff --git a/src/include/platform/CHIPDeviceConfig.h b/src/include/platform/CHIPDeviceConfig.h index 785b47656dd5a3..d7be4de182ebbc 100644 --- a/src/include/platform/CHIPDeviceConfig.h +++ b/src/include/platform/CHIPDeviceConfig.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020-2024 Project CHIP Authors * Copyright (c) 2019-2020 Google LLC. * Copyright (c) 2018 Nest Labs, Inc. * @@ -1507,6 +1507,16 @@ static_assert(CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_MIN <= CHIP_DEVICE // -------------------- Miscellaneous -------------------- +// ----------------------- Terms and Conditions ----------------------- + +#ifndef CHIP_CONFIG_TC_REQUIRED_ACKNOWLEDGEMENTS +#define CHIP_CONFIG_TC_REQUIRED_ACKNOWLEDGEMENTS 0 +#endif + +#ifndef CHIP_CONFIG_TC_REQUIRED_ACKNOWLEDGEMENTS_VERSION +#define CHIP_CONFIG_TC_REQUIRED_ACKNOWLEDGEMENTS_VERSION 0 +#endif + /** * CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES * diff --git a/src/include/platform/KeyValueStoreManager.h b/src/include/platform/KeyValueStoreManager.h index 837750c9f661b8..947f0e377ee5bf 100644 --- a/src/include/platform/KeyValueStoreManager.h +++ b/src/include/platform/KeyValueStoreManager.h @@ -73,8 +73,8 @@ class KeyValueStoreManager * CHIP_ERROR_INVALID_ARGUMENT key is empty or too long or value is * too large */ - CHIP_ERROR Get(const char * key, void * buffer, size_t buffer_size, size_t * read_bytes_size = nullptr, - size_t offset_bytes = 0); + virtual CHIP_ERROR Get(const char * key, void * buffer, size_t buffer_size, size_t * read_bytes_size = nullptr, + size_t offset_bytes = 0); /** * @brief @@ -124,7 +124,7 @@ class KeyValueStoreManager * CHIP_ERROR_INVALID_ARGUMENT key is empty or too long or value is * too large */ - CHIP_ERROR Put(const char * key, const void * value, size_t value_size); + virtual CHIP_ERROR Put(const char * key, const void * value, size_t value_size); /** * @brief @@ -168,15 +168,15 @@ class KeyValueStoreManager * CHIP_ERROR_UNINITIALIZED the KVS is not initialized * CHIP_ERROR_INVALID_ARGUMENT key is empty or too long */ - CHIP_ERROR Delete(const char * key); + virtual CHIP_ERROR Delete(const char * key); private: using ImplClass = ::chip::DeviceLayer::PersistedStorage::KeyValueStoreManagerImpl; protected: // Construction/destruction limited to subclasses. - KeyValueStoreManager() = default; - ~KeyValueStoreManager() = default; + KeyValueStoreManager() = default; + virtual ~KeyValueStoreManager() = default; // No copy, move or assignment. KeyValueStoreManager(const KeyValueStoreManager &) = delete; diff --git a/src/lib/core/BUILD.gn b/src/lib/core/BUILD.gn index eaecf859ac1993..bd7483d701438d 100644 --- a/src/lib/core/BUILD.gn +++ b/src/lib/core/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2022 Project CHIP Authors +# Copyright (c) 2020-2024 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -69,6 +69,8 @@ buildconfig_header("chip_buildconfig") { "CHIP_CONFIG_TLV_VALIDATE_CHAR_STRING_ON_WRITE=${chip_tlv_validate_char_string_on_write}", "CHIP_CONFIG_TLV_VALIDATE_CHAR_STRING_ON_READ=${chip_tlv_validate_char_string_on_read}", "CHIP_CONFIG_COMMAND_SENDER_BUILTIN_SUPPORT_FOR_BATCHED_COMMANDS=${chip_enable_sending_batch_commands}", + "CHIP_CONFIG_TC_REQUIRED_ACKNOWLEDGEMENTS=${chip_tc_required_acknowledgements}", + "CHIP_CONFIG_TC_REQUIRED_ACKNOWLEDGEMENTS_VERSION=${chip_tc_required_acknowledgements_version}", ] visibility = [ ":chip_config_header" ] diff --git a/src/platform/device.gni b/src/platform/device.gni index 01358d4880f876..21d1b866127c0a 100644 --- a/src/platform/device.gni +++ b/src/platform/device.gni @@ -1,4 +1,4 @@ -# Copyright (c) 2020 Project CHIP Authors +# Copyright (c) 2020-2024 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -225,6 +225,14 @@ declare_args() { build_tv_casting_common_a = false } +declare_args() { + # If non-zero, is the terms and conditions required acknowledgements bitfield + chip_tc_required_acknowledgements = 0 + + # If non-zero, is the terms and conditions required version + chip_tc_required_acknowledgements_version = 0 +} + assert(!chip_disable_platform_kvs || chip_device_platform == "darwin", "Can only disable KVS on some platforms") diff --git a/third_party/googletest/BUILD.gn b/third_party/googletest/BUILD.gn new file mode 100644 index 00000000000000..449e6f25057604 --- /dev/null +++ b/third_party/googletest/BUILD.gn @@ -0,0 +1,118 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("${build_root}/config/compiler/compiler.gni") + +config("googletest_config") { + include_dirs = [ + "repo/googletest/include", + "repo/googletest", + ] +} + +static_library("googletest") { + output_name = "libgoogletest" + + include_dirs = [ + "repo/googletest/include", + "repo/googletest", + ] + + sources = [ + "repo/googletest/include/gtest/gtest-assertion-result.h", + "repo/googletest/include/gtest/gtest-death-test.h", + "repo/googletest/include/gtest/gtest-matchers.h", + "repo/googletest/include/gtest/gtest-message.h", + "repo/googletest/include/gtest/gtest-param-test.h", + "repo/googletest/include/gtest/gtest-printers.h", + "repo/googletest/include/gtest/gtest-spi.h", + "repo/googletest/include/gtest/gtest-test-part.h", + "repo/googletest/include/gtest/gtest-typed-test.h", + "repo/googletest/include/gtest/gtest.h", + "repo/googletest/include/gtest/gtest_pred_impl.h", + "repo/googletest/include/gtest/gtest_prod.h", + "repo/googletest/include/gtest/internal/custom/gtest-port.h", + "repo/googletest/include/gtest/internal/custom/gtest-printers.h", + "repo/googletest/include/gtest/internal/custom/gtest.h", + "repo/googletest/include/gtest/internal/gtest-death-test-internal.h", + "repo/googletest/include/gtest/internal/gtest-filepath.h", + "repo/googletest/include/gtest/internal/gtest-internal.h", + "repo/googletest/include/gtest/internal/gtest-param-util.h", + "repo/googletest/include/gtest/internal/gtest-port-arch.h", + "repo/googletest/include/gtest/internal/gtest-port.h", + "repo/googletest/include/gtest/internal/gtest-string.h", + "repo/googletest/include/gtest/internal/gtest-type-util.h", + "repo/googletest/src/gtest-all.cc", + "repo/googletest/src/gtest-assertion-result.cc", + "repo/googletest/src/gtest-death-test.cc", + "repo/googletest/src/gtest-filepath.cc", + "repo/googletest/src/gtest-internal-inl.h", + "repo/googletest/src/gtest-matchers.cc", + "repo/googletest/src/gtest-port.cc", + "repo/googletest/src/gtest-printers.cc", + "repo/googletest/src/gtest-test-part.cc", + "repo/googletest/src/gtest-typed-test.cc", + "repo/googletest/src/gtest.cc", + "repo/googletest/src/gtest_main.cc", + ] + + public_configs = [ ":googletest_config" ] +} + +config("googlemock_config") { + include_dirs = [ + "repo/googlemock/include", + "repo/googlemock", + "repo/googletest/include", + ] +} + +static_library("googlemock") { + output_name = "libgooglemock" + + include_dirs = [ + "repo/googlemock/include", + "repo/googlemock", + "repo/googletest/include", + ] + + sources = [ + "repo/googlemock/include/gmock/gmock-actions.h", + "repo/googlemock/include/gmock/gmock-cardinalities.h", + "repo/googlemock/include/gmock/gmock-function-mocker.h", + "repo/googlemock/include/gmock/gmock-matchers.h", + "repo/googlemock/include/gmock/gmock-more-actions.h", + "repo/googlemock/include/gmock/gmock-more-matchers.h", + "repo/googlemock/include/gmock/gmock-nice-strict.h", + "repo/googlemock/include/gmock/gmock-spec-builders.h", + "repo/googlemock/include/gmock/gmock.h", + "repo/googlemock/include/gmock/internal/custom/gmock-generated-actions.h", + "repo/googlemock/include/gmock/internal/custom/gmock-matchers.h", + "repo/googlemock/include/gmock/internal/custom/gmock-port.h", + "repo/googlemock/include/gmock/internal/gmock-internal-utils.h", + "repo/googlemock/include/gmock/internal/gmock-port.h", + "repo/googlemock/include/gmock/internal/gmock-pp.h", + "repo/googlemock/src/gmock-all.cc", + "repo/googlemock/src/gmock-cardinalities.cc", + "repo/googlemock/src/gmock-internal-utils.cc", + "repo/googlemock/src/gmock-matchers.cc", + "repo/googlemock/src/gmock-spec-builders.cc", + "repo/googlemock/src/gmock.cc", + "repo/googlemock/src/gmock_main.cc", + ] + + deps = [ ":googletest" ] + public_configs = [ ":googlemock_config" ] +} diff --git a/third_party/googletest/repo b/third_party/googletest/repo new file mode 160000 index 00000000000000..f8d7d77c069363 --- /dev/null +++ b/third_party/googletest/repo @@ -0,0 +1 @@ +Subproject commit f8d7d77c06936315286eb55f8de22cd23c188571