Skip to content

Commit

Permalink
Cherry-pick Enhanced Setup Flow to v1.4.1 Release (#37496)
Browse files Browse the repository at this point in the history
* Revert "Update TCUpdateDeadline to be nullable to match spec (#37438) (#37478)"

This reverts commit 37a2d68.

* Fix zap

Something about the last cherry pick broke zap. Re-applying the
changes manually and re-running zap.

* Feature/enhanced setup flow feature (#34065)

* Add initial feature logic for Terms and Conditions (TC) acknowledgements

This commit introduces the initial logic for handling Terms and
Conditions (TC) acknowledgements in the General Commissioning cluster.
The logic includes support for setting and checking TC acknowledgements
and versions during the commissioning process.

Changes include:
- Handling TC acknowledgements and TC acknowledgement version in the
  pairing command.
- Logic to read TC attributes and check TC acceptance in the General
  Commissioning server.
- Introduction of classes to manage TC acceptance logic.
- Initialization and use of TC providers in the server setup.
- Addition of a new commissioning stage for TC acknowledgements in the
  commissioning flow.

The feature logic is currently disabled and will be enabled in an
example in a subsequent commit.

* ./scripts/helpers/restyle-diff.sh @{u}

* Ignore file reference check on TermsAndConditionsManager.cpp

The TermsAndConditionsManager.cpp file is only referenced within sample
apps that utilize the Terms and Conditions feature.

* Make `terms and conditions required` build configurable:

- Moved the configuration from core into app buildconfig
- renamed the flag to expand `TC` into `TERMS AND CONDITIONS`
- updated includes in general-commissioning to include the right header
- added the configuration as a build option into targets.py/host.py
- updated unit test

* Move terms and conditions to its own target and include cpp file

- Create a separate source set for terms and conditions
- include the manager cpp in that file
- make the build conditional (this required flag moving)
- fixed typo in targets.py to make things compile

Compile-tested only (the -terms-and-conditions variant of all clusters
compiled)

* Fix mangled license blurb

* Remove edited date for CHIPConfig.h

* Fix unit tests dependencies

* Add back some includes

---------

Co-authored-by: Andrei Litvin <[email protected]>

* Decouple ember functions from general commissioning cluster (#36836)

* Decouple ember functions from general commissioning cluster

* Address review comments

* Rename gAttrAccess

* Remove new added log info

* Flag SetTCAcknowledgements command

* Revert "Flag SetTCAcknowledgements command"

This reverts commit 90de8a1.

* Add the original debug log back

* feat: Add terms-and-conditions sample app for CI testing (#36950)

* feat: Add terms-and-conditions sample app for CI testing

Add a new sample application that demonstrates and tests the terms and
conditions feature. This app will be integrated into the CI pipeline to
prevent regressions and ensure the feature continues to work as
expected.

The sample app serves as both a reference implementation and an
automated test case for the terms and conditions functionality.

```bash
./scripts/build/build_examples.py --target linux-x64-terms-and-conditions build
```

* Update cluster configurations for app testing

- Enable switch cluster for basic app control testing
- Enable network commissioning cluster for in-app commission testing
- Disable provisional clusters as they are not required
- Disable other non-required clusters to streamline testing setup

This change focuses the cluster configuration on essential components
needed for basic app control and commissioning testing scenarios.

* refactor: Remove unused attributes from Switch cluster

Remove unused attributes from the Switch cluster to comply with the "On/Off Light"
device type specification as defined in the Matter device library v1.4. This change
removes several server-side attributes including ServerList, ClientList, PartsList,
and various internal lists that are not required for the basic On/Off Light
functionality.

* feat: Add Descriptor cluster and enable attribute reporting

Add the mandatory Descriptor cluster to endpoint 1 and enable attribute reporting
for the device. Changes include:
- Add Descriptor cluster with all required attributes (deviceTypeList, serverList, etc.)
- Enable reportable flag for multiple attributes with min/max reporting intervals
- Configure all Descriptor cluster attributes as external callbacks

This change ensures compliance with the Matter specification for the On/Off Light
device type.

* Add Terms and Conditions (T&C) Feature Support for Commissioning (#36863)

* Add Terms and Conditions (T&C) Feature Support for Commissioning

This commit introduces comprehensive support for handling Terms and
Conditions (T&C) during the commissioning process, enhancing
compatibility with Matter device certification requirements.

Key changes include:

1. **Commissioning Process Updates**:
   - Introduced `SetRequireTermsAndConditionsAcknowledgement`,
     `SetTermsAcknowledgements`, and `SetSkipCommissioningComplete` APIs
     in the commissioning library.
   - Updated commissioning stages to include `kGetTCAcknowledgments` and
     `kConfigureTCAcknowledgments` for seamless integration of T&C
     acknowledgements.
   - Added methods for processing T&C acknowledgements and advancing
     commissioning stages upon user response.

2. **Test Framework Enhancements**:
   - Added arguments (`tc_version`, `tc_user_response`,
     `in_test_commissioning_method`) for specifying T&C configuration in
     tests.
   - Enhanced `populate_commissioning_args` to manage new T&C-related
     arguments.
   - Updated Python test bindings and Matter test infrastructure to
     support T&C workflows.

3. **Chip-Tool Improvements**:
   - Extended `PairingCommand` to handle T&C-related arguments
     (`require-tc-acknowledgements`, `tc-acknowledgements`,
     `tc-acknowledgements-version`) for test scenarios.
   - Ensured backward compatibility by defaulting new parameters to
     preserve pre-1.4 behavior.

* Removed the "wait for terms and conditions stage"

The wait-stage is not required. The user input availability must be a
pre-condition for starting the AutoCommissioner process. The wait stage
was previously to support requesting user input after identifying the
device VID/PID using a different channel than within the pairing
payload.

* [doc] Improve Terms and Conditions commissioning arguments documentation

Updated documentation for T&C-related commissioning arguments to better
reflect their actual usage and purpose:

- require-tc-acknowledgements: Clarified the impact on commissioning flow
- tc-acknowledgements: Explained the bit-field usage for user acceptance
- tc-acknowledgements-version: Added context about version tracking

* [controller] Remove T&C acknowledgements from external buffer clearing

The Terms and Conditions acknowledgements parameter was incorrectly included
in ClearExternalBufferDependentValues(). This parameter contains a fixed-size
struct with two uint16_t values and does not reference any external buffers.

The CommissioningParameters class appears to be designed for additive-only
parameter setting without explicit clear/reset functionality, so removing
this inappropriate clearing operation is the correct approach.

* [controller] Fix CommissioningStage enum order for T&C acknowledgements

Move kConfigureTCAcknowledgments before kCleanup in the CommissioningStage
enum to fix cirque test failures. The tests validate that commissioning stages
do not exceed kCleanup, which was causing failures when T&C acknowledgements
were positioned after it.

While the original comment from 2 years ago suggested the enum order was
fixed, testing reveals that the stages can be reordered. The cirque tests
now pass with this corrected ordering, indicating that any previous
constraints on enum ordering no longer apply.

* [doc] Clarify required arguments for T&C acknowledgements

Update help text for require-tc-acknowledgements to explicitly state which
arguments must be provided when T&C acknowledgements are required. Instead
of the vague "valid T&C acknowledgements", now specifically mentions that
both tc-acknowledgements and tc-acknowledgements-version arguments are
mandatory for successful commissioning when this option is enabled.

* Update src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py

Co-authored-by: Tennessee Carmel-Veilleux <[email protected]>

* Restyle

* Renamed variable

---------

Co-authored-by: Tennessee Carmel-Veilleux <[email protected]>

* Remove [commissioner] redundant TC acknowledgement flag (#36966)

* Remove [commissioner] redundant TC acknowledgement flag

The flag controlling whether to require TC acknowledgement is no longer
needed since TC acceptance is now a mandatory pre-condition for
commissioning. This flag was originally added to support delayed TC
acceptance during the commissioning process, but since that flow has
been removed, the flag serves no purpose.

The TC acknowledgement state itself is still required and maintained,
but the additional boolean flag controlling the requirement is redundant
and can be safely removed.

* [chip-tool] Add Enhanced Commissioning Support (T&C Flow via Local DCL) to chip-tool (#37049)

* [chip-tool] Add chip-tool dcl fake cluster commands

* [chip-tool] Add a fake local dcl server script for testing/developement purposes

* [chip-tool] Add chip-tool dcl tc-display and tc-display-by-payload commands

* [General Commissioning Server] Dynamically encode the feature map 'GeneralCommissioning::Feature::kTermsAndConditions' if CHIP_CONFIG_TERMS_AND_CONDITIONS_REQUIRED is set

* [Examples/platform/linux] Set default TermsAndConditions if requested from the command line

* [chip-tool] Add TermsAndConditions support to chip-tool pairing code command

* Reduce the feature level on zap file

* Re-run generate on terms and conditions zap

* test: Implement TC acknowledgement test cases (#37015)

* test: Implement TC acknowledgement test cases 2.5-2.8

Implements test cases for Terms & Conditions acknowledgement verification:
- TC-*-2.5: SetTCAcknowledgements verification
- TC-*-2.6: CommissioningComplete with no terms accepted
- TC-*-2.7: CommissioningComplete with invalid terms
- TC-*-2.8: TCAcknowledgements reset after Factory Reset

Remaining test cases to be implemented in follow-up changes:
- TC-*-2.9: Reset after fabric removal
- TC-*-2.10: Required terms validation
- TC-*-2.11: Post-commission updates

Testing:
Test cases implemented according to test plan specifications.
Each test verifies specific TC acknowledgement behaviors.

* test: Implement remaining TC acknowledgement test cases 2.9-2.11

Implements remaining test cases for Terms & Conditions acknowledgement verification:
- TC-*-2.9: TCAcknowledgements reset after fabric removal
- TC-*-2.10: Required terms validation
- TC-*-2.11: Post-commission TC updates

This completes the test coverage for TC acknowledgement verification,
following up on the previous implementation of test cases 2.5-2.8.
The new test cases verify:
- TC state after fabric removal
- Protection of required terms
- Ability to update TC version and acknowledgements post-commissioning

Testing:
Test cases implemented according to test plan specifications.
Each test verifies specific TC acknowledgement behaviors.

* wip

* feat(testing): Add PICS guard for Terms & Conditions test steps

- Wrap test steps in PICS guard checks for "CGEN.S" and "CGEN.S.F00(TC)"
- Ensure test steps only execute when Terms & Conditions feature flag is enabled
- Maintain test logic while adding conditional execution based on PICS support

* Added PICS and PIXIT definitions to src/app/tests/suites/certification/PICS.yaml

* refactor: Extract commission_devices functionality into reusable methods

Move commissioning logic from CommissionDeviceTest class into standalone
functions to improve code reusability. Introduce CommissioningInfo dataclass
to encapsulate commissioning parameters and add commission_device/
commission_devices helper functions.

The changes:
- Move SetupPayloadInfo dataclass to module level
- Add new CommissioningInfo dataclass for commissioning parameters
- Extract commission_device and commission_devices as standalone async functions
- Add commission_devices method to MatterBaseTest class
- Maintain backward compatibility with existing usage in CommissionDeviceTest

* Addressed PR comments

* Improve test assertions and manual testing steps

- Use Matter-specific type assertions in TC_CGEN_2_5
- Update TC_CGEN_2_8 manual testing flow and prompts

* restyle

* refactor: simplify CGEN feature identifier from CGEN.S.F00(TC) to CGEN.S.F00

- Update PICS.yaml and ci-pics-values to use simplified feature ID
- Update Python test files to use new feature identifier
- Improve error messaging when commissioning feature check fails
- Affected test files: TC_CGEN_2_5 through TC_CGEN_2_11

* Update TC_CGEN_2_5 to use Nullable type for TCUpdateDeadline validation

* Add type validation for TCAcceptedVersion and TCAcknowledgements

* add matter_asserts file from master

* Fix imports on new tests

* fix CI arguments

* Fix bad merge on all_targets_linux_x64.txt

* Remove duplicate commission_devices method to fix F811 flake8 error

Removes the redundant definition of commission_devices method from
MatterBaseTest class to resolve the flake8 F811 error which indicated
a redefinition of an unused function from line 1058.

* fix: Invert boolean return in GetAcknowledgementsRequest (#37014)

* fix: Invert boolean return in GetAcknowledgementsRequest

The GetAcknowledgementsRequest was returning an incorrect boolean value,
causing unexpected behavior. This change inverts the return value to
fix the logical error.

Testing:
- Issue identified during test plan script development
- Test plan changes will be referenced in a separate change

---------

Co-authored-by: Cecille Freeman <[email protected]>
Co-authored-by: Andrei Litvin <[email protected]>
Co-authored-by: Yufeng Wang <[email protected]>
Co-authored-by: Tennessee Carmel-Veilleux <[email protected]>
Co-authored-by: Vivien Nicolas <[email protected]>
  • Loading branch information
6 people authored Feb 11, 2025
1 parent 37a2d68 commit 09d4f61
Show file tree
Hide file tree
Showing 77 changed files with 9,586 additions and 361 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ jobs:
--target linux-x64-fabric-admin-rpc-ipv6only-clang \
--target linux-x64-fabric-bridge-rpc-ipv6only-no-ble-no-wifi-clang \
--target linux-x64-light-data-model-no-unique-id-ipv6only-no-ble-no-wifi-clang \
--target linux-x64-terms-and-conditions \
--target linux-x64-python-bindings \
build \
--copy-artifacts-to objdir-clone \
Expand All @@ -511,6 +512,7 @@ jobs:
echo "FABRIC_ADMIN_APP: out/linux-x64-fabric-admin-rpc-ipv6only-clang/fabric-admin" >> /tmp/test_env.yaml
echo "FABRIC_BRIDGE_APP: out/linux-x64-fabric-bridge-rpc-ipv6only-no-ble-no-wifi-clang/fabric-bridge-app" >> /tmp/test_env.yaml
echo "LIGHTING_APP_NO_UNIQUE_ID: out/linux-x64-light-data-model-no-unique-id-ipv6only-no-ble-no-wifi-clang/chip-lighting-app" >> /tmp/test_env.yaml
echo "TERMS_AND_CONDITIONS_APP: out/linux-x64-terms-and-conditions/chip-terms-and-conditions-app" >> /tmp/test_env.yaml
echo "TRACE_APP: out/trace_data/app-{SCRIPT_BASE_NAME}" >> /tmp/test_env.yaml
echo "TRACE_TEST_JSON: out/trace_data/test-{SCRIPT_BASE_NAME}" >> /tmp/test_env.yaml
echo "TRACE_TEST_PERFETTO: out/trace_data/test-{SCRIPT_BASE_NAME}" >> /tmp/test_env.yaml
Expand Down
15 changes: 15 additions & 0 deletions examples/chip-tool/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ if (config_use_interactive_mode) {
import("//build_overrides/editline.gni")
}

import("${chip_root}/build_overrides/boringssl.gni")
import("${chip_root}/src/crypto/crypto.gni")

assert(chip_build_tools)

config("config") {
Expand Down Expand Up @@ -67,6 +70,14 @@ static_library("chip-tool-utils") {
"commands/common/HexConversion.h",
"commands/common/RemoteDataModelLogger.cpp",
"commands/common/RemoteDataModelLogger.h",
"commands/dcl/DCLClient.cpp",
"commands/dcl/DCLClient.h",
"commands/dcl/DisplayTermsAndConditions.cpp",
"commands/dcl/DisplayTermsAndConditions.h",
"commands/dcl/HTTPSRequest.cpp",
"commands/dcl/HTTPSRequest.h",
"commands/dcl/JsonSchemaMacros.cpp",
"commands/dcl/JsonSchemaMacros.h",
"commands/delay/SleepCommand.cpp",
"commands/delay/WaitForCommissioneeCommand.cpp",
"commands/discover/DiscoverCommand.cpp",
Expand Down Expand Up @@ -102,6 +113,10 @@ static_library("chip-tool-utils") {
sources += [ "commands/common/DeviceScanner.cpp" ]
}

if (chip_device_platform == "darwin" || chip_crypto == "boringssl") {
deps += [ "${boringssl_root}:boringssl_with_ssl_sources" ]
}

public_deps = [
"${chip_root}/examples/common/tracing:commandline",
"${chip_root}/src/app/icd/client:handler",
Expand Down
37 changes: 37 additions & 0 deletions examples/chip-tool/commands/dcl/Commands.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2022 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 "commands/common/Commands.h"
#include "commands/dcl/DCLCommands.h"

void registerCommandsDCL(Commands & commands)
{
const char * clusterName = "DCL";
commands_list clusterCommands = {
make_unique<DCLModelCommand>(), //
make_unique<DCLModelByPayloadCommand>(), //
make_unique<DCLTCCommand>(), //
make_unique<DCLTCByPayloadCommand>(), //
make_unique<DCLTCDisplayCommand>(), //
make_unique<DCLTCDisplayByPayloadCommand>(), //
};

commands.RegisterCommandSet(clusterName, clusterCommands, "Commands to interact with the DCL.");
}
241 changes: 241 additions & 0 deletions examples/chip-tool/commands/dcl/DCLClient.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
/*
* 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 "DCLClient.h"

#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <setup_payload/ManualSetupPayloadParser.h>
#include <setup_payload/QRCodeSetupPayloadParser.h>

#include "HTTPSRequest.h"
#include "JsonSchemaMacros.h"

namespace {
constexpr const char * kDefaultDCLHostName = "on.dcl.csa-iot.org";
constexpr const char * kErrorSchemaValidation = "Model schema validation failed for response content: ";
constexpr const char * kErrorVendorIdIsZero = "Invalid argument: Vendor ID should not be 0";
constexpr const char * kErrorProductIdIsZero = "Invalid argument: Product ID should not be 0";
constexpr const char * kErrorOrdinalValueTooLarge = "Ordinal value exceeds the maximum allowable bits: ";
constexpr const char * kRequestModelVendorProductPath = "/dcl/model/models/%u/%u";
constexpr uint8_t kRequestPathBufferSize = 64;
constexpr uint16_t kTermsAndConditionSchemaVersion = 1;
} // namespace

namespace chip {
namespace tool {
namespace dcl {

namespace {
CHIP_ERROR ValidateModelSchema(const Json::Value & json)
{
CHECK_REQUIRED_TYPE(json, model, Object)
auto model = json["model"];

CHECK_REQUIRED_TYPE(model, commissioningCustomFlow, UInt);

// The "enhancedSetupFlowOptions" field is theoretically required by the schema.
// However, the current DCL implementation does not include it.
// To handle this gracefully, we inject the field and set its value to 0 if it is missing.
if (!model.isMember("enhancedSetupFlowOptions"))
{
model["enhancedSetupFlowOptions"] = 0;
}

CHECK_REQUIRED_TYPE(model, enhancedSetupFlowOptions, UInt)

// Check if enhancedSetupFlowOptions has bit 0 set.
// Bit 0 indicates that enhanced setup flow is enabled.
auto enhancedSetupFlowOptions = model["enhancedSetupFlowOptions"];
VerifyOrReturnError((enhancedSetupFlowOptions.asUInt() & 0x01) != 0, CHIP_NO_ERROR);

// List of required keys in the "model" object if enhancedSetupFlowOptions has bit 0 set.
CHECK_REQUIRED_TYPE(model, enhancedSetupFlowTCUrl, String)
CHECK_REQUIRED_TYPE(model, enhancedSetupFlowTCDigest, String)
CHECK_REQUIRED_TYPE(model, enhancedSetupFlowTCFileSize, UInt)
CHECK_REQUIRED_TYPE(model, enhancedSetupFlowTCRevision, UInt)
CHECK_REQUIRED_TYPE(model, enhancedSetupFlowMaintenanceUrl, String)

return CHIP_NO_ERROR;
}

CHIP_ERROR ValidateModelCustomFlow(const Json::Value & json, CommissioningFlow payloadCommissioningFlow)
{
auto model = json["model"];
CHECK_REQUIRED_VALUE(model, commissioningCustomFlow, to_underlying(payloadCommissioningFlow))
return CHIP_NO_ERROR;
}

CHIP_ERROR ValidateTCLanguageEntries(const Json::Value & languageEntries)
{
for (Json::Value::const_iterator it = languageEntries.begin(); it != languageEntries.end(); it++)
{
const Json::Value & languageArray = *it;

CHECK_TYPE(languageArray, languageArray, Array);

for (Json::ArrayIndex i = 0; i < languageArray.size(); i++)
{
const Json::Value & term = languageArray[i];
CHECK_REQUIRED_TYPE(term, title, String);
CHECK_REQUIRED_TYPE(term, text, String);
CHECK_REQUIRED_TYPE(term, required, Bool);
CHECK_REQUIRED_TYPE(term, ordinal, UInt);

auto ordinal = term["ordinal"].asUInt();
VerifyOrReturnError(ordinal < 16, CHIP_ERROR_INVALID_ARGUMENT,
ChipLogError(chipTool, "%s%u", kErrorOrdinalValueTooLarge, ordinal));
}
}

return CHIP_NO_ERROR;
}

CHIP_ERROR ValidateTCCountryEntries(const Json::Value & countryEntries)
{
for (Json::Value::const_iterator it = countryEntries.begin(); it != countryEntries.end(); it++)
{
const Json::Value & countryEntry = *it;

CHECK_REQUIRED_TYPE(countryEntry, defaultLanguage, String);
CHECK_REQUIRED_TYPE(countryEntry, languageEntries, Object);

ReturnErrorOnFailure(ValidateTCLanguageEntries(countryEntry["languageEntries"]));
}

return CHIP_NO_ERROR;
}

CHIP_ERROR ValidateTermsAndConditionsSchema(const Json::Value & tc, unsigned int expectedEnhancedSetupFlowTCRevision)
{
CHECK_REQUIRED_VALUE(tc, schemaVersion, kTermsAndConditionSchemaVersion)
CHECK_REQUIRED_TYPE(tc, esfRevision, UInt)
CHECK_REQUIRED_TYPE(tc, defaultCountry, String)
CHECK_REQUIRED_TYPE(tc, countryEntries, Object)
CHECK_REQUIRED_VALUE(tc, esfRevision, expectedEnhancedSetupFlowTCRevision)
return ValidateTCCountryEntries(tc["countryEntries"]);
}

CHIP_ERROR RequestTermsAndConditions(const Json::Value & json, Json::Value & tc)
{
auto & model = json["model"];
if ((model["enhancedSetupFlowOptions"].asUInt() & 0x01) == 0)
{
ChipLogProgress(chipTool,
"Enhanced setup flow is not enabled for this model (bit 0 of enhancedSetupFlowOptions is not set). No "
"Terms and Conditions are required for this configuration.");
tc = Json::nullValue;
return CHIP_NO_ERROR;
}

auto & enhancedSetupFlowTCUrl = model["enhancedSetupFlowTCUrl"];
auto & enhancedSetupFlowTCFileSize = model["enhancedSetupFlowTCFileSize"];
auto & enhancedSetupFlowTCDigest = model["enhancedSetupFlowTCDigest"];
auto & enhancedSetupFlowTCRevision = model["enhancedSetupFlowTCRevision"];

auto * tcUrl = enhancedSetupFlowTCUrl.asCString();
const auto optionalFileSize = MakeOptional(static_cast<uint32_t>(enhancedSetupFlowTCFileSize.asUInt()));
const auto optionalDigest = MakeOptional(enhancedSetupFlowTCDigest.asCString());
ReturnErrorOnFailure(https::Request(tcUrl, tc, optionalFileSize, optionalDigest));
ReturnErrorOnFailure(ValidateTermsAndConditionsSchema(tc, enhancedSetupFlowTCRevision.asUInt()));

return CHIP_NO_ERROR;
}

} // namespace

DCLClient::DCLClient(Optional<const char *> hostname, Optional<uint16_t> port)
{
mHostName = hostname.ValueOr(kDefaultDCLHostName);
mPort = port.ValueOr(0);
}

CHIP_ERROR DCLClient::Model(const char * onboardingPayload, Json::Value & outModel)
{
SetupPayload payload;
bool isQRCode = strncmp(onboardingPayload, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
if (isQRCode)
{
ReturnErrorOnFailure(QRCodeSetupPayloadParser(onboardingPayload).populatePayload(payload));
VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
}
else
{
ReturnErrorOnFailure(ManualSetupPayloadParser(onboardingPayload).populatePayload(payload));
VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
}

auto vendorId = static_cast<VendorId>(payload.vendorID);
auto productId = payload.productID;

// If both vendorId and productId are zero, return a null model without error.
if (vendorId == 0 && productId == 0)
{
ChipLogProgress(chipTool, "Vendor ID and Product ID not found in the provided payload. DCL lookup will not be used.");
outModel = Json::nullValue;
return CHIP_NO_ERROR;
}

ReturnErrorOnFailure(Model(vendorId, productId, outModel));

auto commissioningFlow = payload.commissioningFlow;
CHIP_ERROR error = ValidateModelCustomFlow(outModel, commissioningFlow);
VerifyOrReturnError(CHIP_NO_ERROR == error, error,
ChipLogError(chipTool, "%s%s", kErrorSchemaValidation, outModel.toStyledString().c_str()));

return CHIP_NO_ERROR;
}

CHIP_ERROR DCLClient::Model(const chip::VendorId vendorId, const uint16_t productId, Json::Value & outModel)
{
VerifyOrReturnError(0 != vendorId, CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(chipTool, "%s", kErrorVendorIdIsZero));
VerifyOrReturnError(0 != productId, CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(chipTool, "%s", kErrorProductIdIsZero));

char path[kRequestPathBufferSize];
VerifyOrReturnError(snprintf(path, sizeof(path), kRequestModelVendorProductPath, to_underlying(vendorId), productId) >= 0,
CHIP_ERROR_INVALID_ARGUMENT);
ReturnErrorOnFailure(https::Request(mHostName, mPort, path, outModel));

CHIP_ERROR error = ValidateModelSchema(outModel);
VerifyOrReturnError(CHIP_NO_ERROR == error, error,
ChipLogError(chipTool, "%s%s", kErrorSchemaValidation, outModel.toStyledString().c_str()));

return CHIP_NO_ERROR;
}

CHIP_ERROR DCLClient::TermsAndConditions(const char * onboardingPayload, Json::Value & outTc)
{
Json::Value json;
ReturnErrorOnFailure(Model(onboardingPayload, json));
VerifyOrReturnError(Json::nullValue != json.type(), CHIP_NO_ERROR, outTc = Json::nullValue);
ReturnErrorOnFailure(RequestTermsAndConditions(json, outTc));
return CHIP_NO_ERROR;
}

CHIP_ERROR DCLClient::TermsAndConditions(const chip::VendorId vendorId, const uint16_t productId, Json::Value & outTc)
{
Json::Value json;
ReturnErrorOnFailure(Model(vendorId, productId, json));
VerifyOrReturnError(Json::nullValue != json.type(), CHIP_NO_ERROR, outTc = Json::nullValue);
ReturnErrorOnFailure(RequestTermsAndConditions(json, outTc));
return CHIP_NO_ERROR;
}

} // namespace dcl
} // namespace tool
} // namespace chip
Loading

0 comments on commit 09d4f61

Please sign in to comment.