diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index dc152c1a714f19..4297e791326786 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -26,14 +26,14 @@ on: run-codeql: required: false type: boolean - + concurrency: group: ${{ github.ref }}-${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.event.number) || (github.event_name == 'workflow_dispatch' && github.run_number) || github.sha }} cancel-in-progress: true env: CHIP_NO_LOG_TIMESTAMPS: true - + jobs: build_linux_gcc_debug: name: Build on Linux (gcc_debug) @@ -210,7 +210,7 @@ jobs: ./scripts/run_in_build_env.sh \ "./scripts/run-clang-tidy-on-compile-commands.py \ --compile-database out/sanitizers/compile_commands.json \ - --file-exclude-regex '/(repo|zzz_generated|lwip/standalone)/|-ReadImpl|-InvokeSubscribeImpl|CodegenDataModel_Write' \ + --file-exclude-regex '/(repo|zzz_generated|lwip/standalone)/|-ReadImpl|-InvokeSubscribeImpl|CodegenDataModel_Write|QuieterReporting' \ check \ " - name: Clean output @@ -243,7 +243,7 @@ jobs: run: | rm -rf ./zzz_pregenerated mv scripts/codegen.py.renamed scripts/codegen.py - mv scripts/tools/zap/generate.py.renamed scripts/tools/zap/generate.py + mv scripts/tools/zap/generate.py.renamed scripts/tools/zap/generate.py - name: Run fake linux tests with build_examples run: | ./scripts/run_in_build_env.sh \ @@ -253,7 +253,7 @@ jobs: uses: ./.github/actions/perform-codeql-analysis with: language: cpp - + - name: Uploading core files uses: actions/upload-artifact@v4 if: ${{ failure() && !env.ACT }} @@ -430,7 +430,7 @@ jobs: ./scripts/run_in_build_env.sh \ "./scripts/run-clang-tidy-on-compile-commands.py \ --compile-database out/default/compile_commands.json \ - --file-exclude-regex '/(repo|zzz_generated|lwip/standalone)/|CodegenDataModel_Write' \ + --file-exclude-regex '/(repo|zzz_generated|lwip/standalone)/|CodegenDataModel_Write|QuieterReporting' \ check \ " - name: Uploading diagnostic logs @@ -445,7 +445,7 @@ jobs: uses: ./.github/actions/perform-codeql-analysis with: language: cpp - + # TODO Log Upload https://github.com/project-chip/connectedhomeip/issues/2227 # TODO https://github.com/project-chip/connectedhomeip/issues/1512 diff --git a/.github/workflows/examples-nxp.yaml b/.github/workflows/examples-nxp.yaml index 05d434b0a67792..07ab55d1315bb5 100644 --- a/.github/workflows/examples-nxp.yaml +++ b/.github/workflows/examples-nxp.yaml @@ -60,14 +60,14 @@ jobs: run: | scripts/run_in_build_env.sh "\ ./scripts/build/build_examples.py \ - --target nxp-k32w0-lighting \ - --target nxp-k32w0-lighting-factory \ - --target nxp-k32w0-lighting-rotating-id \ - --target nxp-k32w0-contact-sensor \ - --target nxp-k32w0-contact-sensor-low-power \ - --target nxp-k32w0-contact-sensor-low-power-factory \ - --target nxp-k32w1-lighting \ - --target nxp-k32w1-contact-sensor-low-power \ + --target nxp-k32w0-freertos-lighting \ + --target nxp-k32w0-freertos-lighting-factory \ + --target nxp-k32w0-freertos-lighting-rotating-id \ + --target nxp-k32w0-freertos-contact-sensor \ + --target nxp-k32w0-freertos-contact-sensor-low-power \ + --target nxp-k32w0-freertos-contact-sensor-low-power-factory \ + --target nxp-k32w1-freertos-lighting \ + --target nxp-k32w1-freertos-contact-sensor-low-power \ build \ --copy-artifacts-to out/artifacts \ " @@ -75,21 +75,21 @@ jobs: run: | .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nxp k32w0+release light \ - out/artifacts/nxp-k32w0-lighting/chip-k32w0x-light-example.elf \ + out/artifacts/nxp-k32w0-freertos-lighting/chip-k32w0x-light-example.elf \ /tmp/bloat_reports/ .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nxp k32w1+release light \ - out/artifacts/nxp-k32w1-lighting/chip-k32w1-light-example.elf \ + out/artifacts/nxp-k32w1-freertos-lighting/chip-k32w1-light-example.elf \ /tmp/bloat_reports/ - name: Get contact sensor size stats run: | .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nxp k32w0+release contact \ - out/artifacts/nxp-k32w0-contact-sensor-low-power/chip-k32w0x-contact-example.elf \ + out/artifacts/nxp-k32w0-freertos-contact-sensor-low-power/chip-k32w0x-contact-example.elf \ /tmp/bloat_reports/ .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nxp k32w1+release contact \ - out/artifacts/nxp-k32w1-contact-sensor-low-power/chip-k32w1-contact-example.elf \ + out/artifacts/nxp-k32w1-freertos-contact-sensor-low-power/chip-k32w1-contact-example.elf \ /tmp/bloat_reports/ - name: Uploading Size Reports uses: ./.github/actions/upload-size-reports diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index a8bdfdcdc2c1ec..53195008ba4222 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -112,6 +112,7 @@ jobs: src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/clusters-extensions.xml \ src/app/zap-templates/zcl/data-model/chip/color-control-cluster.xml \ + src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/concentration-measurement-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml \ @@ -191,6 +192,7 @@ jobs: src/app/zap-templates/zcl/data-model/chip/unit-localization-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/wake-on-lan-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/washer-controls-cluster.xml \ + src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/window-covering.xml \ @@ -493,7 +495,7 @@ jobs: - name: Run Tests run: | mkdir -p out/trace_data - scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --quiet --app-args "--trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script-args "--log-level INFO -t 3600 --disable-test ClusterObjectTests.TestTimedRequestTimeout --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/controller/python/test/test_scripts/mobile-device-test.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_ACE_1_2.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_ACE_1_3.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_ACE_1_4.py' @@ -529,6 +531,7 @@ jobs: scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_ICDManagementCluster.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_IDM_1_2.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_IDM_1_4.py' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_IDM_4_2.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_PWRTL_2_1.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_RR_1_1.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_SC_3_6.py' @@ -579,6 +582,7 @@ jobs: scripts/run_in_python_env.sh out/venv './scripts/tests/TestTimeSyncTrustedTimeSourceRunner.py' scripts/run_in_python_env.sh out/venv './src/python_testing/test_testing/test_TC_ICDM_2_1.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestIdChecks.py' + scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/test_testing/test_IDM_10_4.py' - name: Uploading core files uses: actions/upload-artifact@v4 diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index e2f9dcc099eba6..c742ddb0336764 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -330,9 +330,11 @@ menu "CHIP Device Layer" config MAX_EVENT_QUEUE_SIZE int "Max Event Queue Size" range 0 65535 - default 25 + default 40 help The maximum number of events that can be held in the CHIP Platform event queue. + Should be set greater than CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM. For SoCs other than + ESP32-C2, where the Wi-Fi buffer number is 8, recommended to use the default value. config ENABLE_EXTENDED_DISCOVERY bool "Enable Extended discovery Support" diff --git a/config/python/CHIPProjectConfig.h b/config/python/CHIPProjectConfig.h index 5effaaa13c6479..4412c5bec75a01 100644 --- a/config/python/CHIPProjectConfig.h +++ b/config/python/CHIPProjectConfig.h @@ -26,14 +26,19 @@ #define CHIP_CONFIG_EVENT_LOGGING_NUM_EXTERNAL_CALLBACKS 2 // Uncomment this for a large Tunnel MTU. -//#define CHIP_CONFIG_TUNNEL_INTERFACE_MTU (9000) +// #define CHIP_CONFIG_TUNNEL_INTERFACE_MTU (9000) // Enable support functions for parsing command-line arguments #define CHIP_CONFIG_ENABLE_ARG_PARSER 1 -// Use a default pairing code if one hasn't been provisioned in flash. -#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 -#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +// Enable use of test setup parameters for testing purposes only. +// +// WARNING: This option makes it possible to circumvent basic chip security functionality. +// Because of this it SHOULD NEVER BE ENABLED IN PRODUCTION BUILDS. +// +#ifndef CHIP_DEVICE_CONFIG_ENABLE_TEST_SETUP_PARAMS +#define CHIP_DEVICE_CONFIG_ENABLE_TEST_SETUP_PARAMS 1 +#endif // Enable reading DRBG seed data from /dev/(u)random. // This is needed for test applications and the CHIP device manager to function @@ -46,6 +51,8 @@ // WARNING: These options make it possible to circumvent basic Chip security functionality, // including message encryption. Because of this they MUST NEVER BE ENABLED IN PRODUCTION BUILDS. // +// To build with this flag, pass 'treat_warnings_as_errors=false' to gn/ninja. +// #define CHIP_CONFIG_SECURITY_TEST_MODE 0 #define CHIP_CONFIG_ENABLE_UPDATE 1 diff --git a/docs/getting_started/SDKBasics.md b/docs/getting_started/SDKBasics.md index fee03ae7cd484d..7f2c81f285fceb 100644 --- a/docs/getting_started/SDKBasics.md +++ b/docs/getting_started/SDKBasics.md @@ -58,7 +58,7 @@ logic is handled in the run-time installed interface layers. - examples - [examples/chip-tool](https://github.com/project-chip/connectedhomeip/blob/master/examples/chip-tool) - main controller example - - [examples/all-clusters-app](https://github.com/project-chip/connectedhomeip/blob/master/examples/all-cluster-app) - + - [examples/all-clusters-app](https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app) - QA app - [examples/\](https://github.com/project-chip/connectedhomeip/blob/master/examples) - Specific Device examples diff --git a/docs/guides/fabric_synchronization_guide.md b/docs/guides/fabric_synchronization_guide.md new file mode 100644 index 00000000000000..36107744a97930 --- /dev/null +++ b/docs/guides/fabric_synchronization_guide.md @@ -0,0 +1,164 @@ +# Fabric Synchronization Guide + +- [Fabric Synchronization Guide](#fabric-synchronization-guide) + - [Fabric Sync Example Applications](#fabric-sync-example-applications) + - [Run Fabric Sync Demo on RP4](#run-fabric-sync-demo-on-rp4) + +## Fabric Sync Example Applications + +Fabric-Admin and Fabric-Bridge example applications are provided to demonstrate +Fabric Synchronization feature. You can find them in the examples. + +![matter_fabric_synchronization](images/matter_fabric_synchronization.png) + +Fabric-Admin example app implements the Fabric Administrator role and +communicates with the Fabric-Bridge-App on the other side, facilitating the +Fabric Synchronization process. + +Fabric-Bridge-App example app implements the Aggregator device type with Fabric +Synchronization condition met and demonstrates the end-to-end Fabric +Synchronization feature using dynamic endpoints. + +Fabric Synchronization can be triggered from either side. The initiator of the +Fabric Synchronization process, who shares their devices, takes on the +Commissioner role. The recipient of the Fabric Synchronization request, who +receives the shared devices, assumes the Commissionee role. This flexibility +enables a seamless and efficient synchronization process. + +### Building the Example Application + +- Building the Fabric-Admin Application + + [Fabric-Admin](https://github.com/project-chip/connectedhomeip/tree/master/examples/fabric-admin/README.md) + +* Building the Fabric-Bridge Application + + [Fabric-Bridge](https://github.com/project-chip/connectedhomeip/tree/master/examples/fabric-bridge-app/linux/README.md) + +## Run Fabric Sync Demo on RP4 + +### Setup Fabric Source + +Connect to the Fabric Source server: + +``` +ssh ubuntu@xxx.xxx.xxx.xxx +``` + +Password: + +Run the Fabric Source script: + +``` +./run_fabric_source.sh +``` + +### Setup Fabric Sink + +Connect to the Fabric Sink server: + +``` +ssh ubuntu@xxx.xxx.xxx.xxx +``` + +Password: + +Run the Fabric Sink script: + +``` +./run_fabric_sink.sh +``` + +### Fabric Sync Setup + +Enable Fabric Auto Sync: + +In Fabric-Sync console: + +``` +fabricsync enable-auto-sync 1 +``` + +Pair the Fabric-Source bridge to Fabric-Sync with node ID 1: + +``` +fabricsync add-bridge 1 +``` + +### Pair Light Example to Fabric-Source + +Pair the Light Example with node ID 3 using its payload number: + +``` +pairing already-discovered 3 20202021 5540 +``` + +After the Light Example is successfully paired in Fabric-Source, it will be +synced to Fabric-Sink with a new assigned node ID. + +Toggle the Light Example: + +From Fabric-Source: + +``` +onoff on 1 +onoff off 1 +``` + +From Fabric-Sink: (Use the node ID assigned) + +``` +onoff on x 1 +onoff off x 1 +``` + +### Remove Light Example from Fabric-Source + +Unpair the Light Example: + +``` +pairing unpair +``` + +After the Light Example is successfully unpaired from Fabric-Source, it will +also be removed from the Fabric-Sink. + +### Pair Commercial Switch to Fabric-Source + +Pair the switch using its payload number: + +In Fabric-Source console: + +``` +pairing code-wifi +``` + +After the switch is successfully paired in Fabric-Source, it will be synced to +Fabric-Sink with a new assigned node ID. + +Toggle the switch: + +From Fabric-Source: + +``` +onoff on 1 +onoff off 1 +``` + +From Fabric-Sink: (Use the node ID assigned) + +``` +onoff on 1 +onoff off 1 +``` + +### Remove Switch from Fabric-Source + +Unpair the switch: + +``` +pairing unpair +``` + +After the switch is successfully unpaired from Fabric-Source, it will also be +removed from the Fabric-Sink. diff --git a/docs/guides/images/matter_fabric_synchronization.png b/docs/guides/images/matter_fabric_synchronization.png new file mode 100644 index 00000000000000..95c99c4fe150b9 Binary files /dev/null and b/docs/guides/images/matter_fabric_synchronization.png differ diff --git a/docs/testing/python.md b/docs/testing/python.md index 06051fee4fb33b..5745a301535fc7 100644 --- a/docs/testing/python.md +++ b/docs/testing/python.md @@ -85,58 +85,8 @@ The default_matter_test_main() function is used to run the test on the command line. These two lines should appear verbatim at the bottom of every python test file. -## Defining the test arguments - -Below is the format: - -``` -# test-runner-runs: -# test-runner-run//app: ${TYPE_OF_APP} -# test-runner-run//factoryreset: -# test-runner-run//quiet: -# test-runner-run//app-args: -# test-runner-run//script-args: -``` - -### Description of Parameters - -- test-runner-runs: Specifies the identifier for the run. This can be any - unique identifier. - - - Example: run1 - -- test-runner-run//app: Indicates the application to be used - in the test. Different app types as needed could be referenced from section - [name: Generate an argument environment file ] of the file - [.github/workflows/tests.yaml](https://github.com/project-chip/connectedhomeip/blob/master/.github/workflows/tests.yaml) - - - Example: \${TYPE_OF_APP} - -- test-runner-run//factoryreset: Determines whether a factory - reset should be performed before the test. - - - Example: True - -- test-runner-run//quiet: Sets the verbosity level of the test - run. When set to True, the test run will be quieter. - - - Example: True - -- test-runner-run//app-args: Specifies the arguments to be - passed to the application during the test. - - - Example: --discriminator 1234 --KVS kvs1 --trace-to - json:\${TRACE_APP}.json - -- test-runner-run//script-args: Specifies the arguments to be - passed to the test script. - - Example: --storage-path admin_storage.json --commissioning-method - on-network --discriminator 1234 --passcode 20202021 --trace-to - json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto - -This structured format ensures that all necessary configurations are clearly -defined and easily understood, allowing for consistent and reliable test -execution. +The structured comments above the class definition are used to set up the CI for +the tests. Please see [Running tests in CI](#running-tests-in-ci). ## Cluster Codegen @@ -610,3 +560,63 @@ example DUT on the host and includes factory reset support - if there are things in your test that will fail on CI (ex. test vendor checks), gate them on the PICS_SDK_CI_ONLY - is_ci = self.check_pics('PICS_SDK_CI_ONLY') + +The CI test runner uses a structured environment setup that can be declared +using structured comments at the top of the test file. To use this structured +format, use the --load-from-env flag with the run_python_tests.py runner. + +Ex: +`scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_ICDM_2_1.py'` + +## Defining the CI test arguments + +Below is the format: + +``` +# test-runner-runs: +# test-runner-run//app: ${TYPE_OF_APP} +# test-runner-run//factoryreset: +# test-runner-run//quiet: +# test-runner-run//app-args: +# test-runner-run//script-args: +``` + +### Description of Parameters + +- test-runner-runs: Specifies the identifier for the run. This can be any + unique identifier. + + - Example: run1 + +- test-runner-run//app: Indicates the application to be used + in the test. Different app types as needed could be referenced from section + [name: Generate an argument environment file ] of the file + [.github/workflows/tests.yaml](https://github.com/project-chip/connectedhomeip/blob/master/.github/workflows/tests.yaml) + + - Example: \${TYPE_OF_APP} + +- test-runner-run//factoryreset: Determines whether a factory + reset should be performed before the test. + + - Example: True + +- test-runner-run//quiet: Sets the verbosity level of the test + run. When set to True, the test run will be quieter. + + - Example: True + +- test-runner-run//app-args: Specifies the arguments to be + passed to the application during the test. + + - Example: --discriminator 1234 --KVS kvs1 --trace-to + json:\${TRACE_APP}.json + +- test-runner-run//script-args: Specifies the arguments to be + passed to the test script. + - Example: --storage-path admin_storage.json --commissioning-method + on-network --discriminator 1234 --passcode 20202021 --trace-to + json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto + +This structured format ensures that all necessary configurations are clearly +defined and easily understood, allowing for consistent and reliable test +execution. diff --git a/docs/testing/unit_testing.md b/docs/testing/unit_testing.md index 64046a4c21a9d6..243e35d9b380c9 100644 --- a/docs/testing/unit_testing.md +++ b/docs/testing/unit_testing.md @@ -218,8 +218,8 @@ your overriding function make sure to check `HasFailure()` and return if the parent function failed. If you don't override any of the setup/teardown functions, you can simply make a -type alias: `using YourTestContext = Test::AppContextPW;` instead of defining -your own text context class. +type alias: `using YourTestContext = Test::AppContext;` instead of defining your +own text context class. ## Best practices diff --git a/docs/zap_clusters.md b/docs/zap_clusters.md index 7651e35b784ed1..dc439fa2f37607 100644 --- a/docs/zap_clusters.md +++ b/docs/zap_clusters.md @@ -79,6 +79,7 @@ Generally regenerate using one of: | 129 | 0x81 | ValveConfigurationAndControl | | 144 | 0x90 | ElectricalPowerMeasurement | | 145 | 0x91 | ElectricalEnergyMeasurement | +| 148 | 0x94 | WaterHeaterManagement | | 150 | 0x96 | DemandResponseLoadControl | | 151 | 0x97 | Messages | | 152 | 0x98 | DeviceEnergyManagement | @@ -130,6 +131,7 @@ Generally regenerate using one of: | 1294 | 0x50E | AccountLogin | | 1295 | 0x50F | ContentControl | | 1296 | 0x510 | ContentAppObserver | +| 1873 | 0x751 | CommissionerControl | | 2820 | 0xB04 | ElectricalMeasurement | | 4294048773 | 0xFFF1FC05 | UnitTesting | | 4294048774 | 0xFFF1FC06 | FaultInjection | diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index b512a6b1399d58..b3ae5b1f385a74 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -2731,8 +2731,8 @@ cluster OvenMode = 73 { command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } -/** This cluster supports remotely monitoring and controling the different typs of - functionality available to a drying device, such as a laundry dryer. */ +/** This cluster provides a way to access options associated with the operation of + a laundry dryer device type. */ cluster LaundryDryerControls = 74 { revision 1; @@ -4298,7 +4298,7 @@ provisional cluster DeviceEnergyManagement = 152 { /** Electric Vehicle Supply Equipment (EVSE) is equipment used to charge an Electric Vehicle (EV) or Plug-In Hybrid Electric Vehicle. This cluster provides an interface to the functionality of Electric Vehicle Supply Equipment (EVSE) management. */ cluster EnergyEvse = 153 { - revision 2; + revision 4; enum EnergyTransferStoppedReasonEnum : enum8 { kEVStopped = 0; @@ -4342,6 +4342,7 @@ cluster EnergyEvse = 153 { kDischargingEnabled = 2; kDisabledError = 3; kDisabledDiagnostics = 4; + kEnabled = 5; } bitmap Feature : bitmap32 { @@ -4389,6 +4390,7 @@ cluster EnergyEvse = 153 { int32u sessionID = 0; StateEnum state = 1; amperage_ma maximumCurrent = 2; + optional amperage_ma maximumDischargeCurrent = 3; } info event EnergyTransferStopped = 3 { @@ -4396,6 +4398,7 @@ cluster EnergyEvse = 153 { StateEnum state = 1; EnergyTransferStoppedReasonEnum reason = 2; energy_mwh energyTransferred = 4; + optional energy_mwh energyDischarged = 5; } critical event Fault = 4 { @@ -4460,15 +4463,15 @@ cluster EnergyEvse = 153 { /** Allows a client to disable the EVSE from charging and discharging. */ timed command Disable(): DefaultSuccess = 1; - /** Allows a client to enable the EVSE to charge an EV. */ + /** This command allows a client to enable the EVSE to charge an EV, */ timed command EnableCharging(EnableChargingRequest): DefaultSuccess = 2; - /** Allows a client to enable the EVSE to discharge an EV. */ + /** Upon receipt, this SHALL allow a client to enable the discharge of an EV, */ timed command EnableDischarging(EnableDischargingRequest): DefaultSuccess = 3; /** Allows a client to put the EVSE into a self-diagnostics mode. */ timed command StartDiagnostics(): DefaultSuccess = 4; /** Allows a client to set the user specified charging targets. */ timed command SetTargets(SetTargetsRequest): DefaultSuccess = 5; - /** Allows a client to retrieve the user specified charging targets. */ + /** Allows a client to retrieve the current set of charging targets. */ timed command GetTargets(): GetTargetsResponse = 6; /** Allows a client to clear all stored charging targets. */ timed command ClearTargets(): DefaultSuccess = 7; diff --git a/examples/all-clusters-app/esp32/sdkconfig.defaults.esp32c2 b/examples/all-clusters-app/esp32/sdkconfig.defaults.esp32c2 index 6cb90db4f55b9d..200dc5825bc2e2 100644 --- a/examples/all-clusters-app/esp32/sdkconfig.defaults.esp32c2 +++ b/examples/all-clusters-app/esp32/sdkconfig.defaults.esp32c2 @@ -17,3 +17,6 @@ CONFIG_BT_NIMBLE_ROLE_OBSERVER=n CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=4 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=8 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=16 + +# Event Queue Size +CONFIG_MAX_EVENT_QUEUE_SIZE=25 diff --git a/examples/all-clusters-app/nxp/zephyr/.gitignore b/examples/all-clusters-app/nxp/zephyr/.gitignore new file mode 100644 index 00000000000000..84c048a73cc2e5 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/examples/all-clusters-app/nxp/zephyr/CMakeLists.txt b/examples/all-clusters-app/nxp/zephyr/CMakeLists.txt new file mode 100644 index 00000000000000..2fa2d558a2724a --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/CMakeLists.txt @@ -0,0 +1,115 @@ +# +# Copyright (c) 2023-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. +# +cmake_minimum_required(VERSION 3.13.1) + +get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connectedhomeip REALPATH) +get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) +get_filename_component(ALL_CLUSTERS_COMMON_DIR ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) +get_filename_component(ALL_CLUSTERS_NXP_COMMON_DIR ${CHIP_ROOT}/examples/all-clusters-app/nxp/common REALPATH) +get_filename_component(EXAMPLE_PLATFORM_NXP_COMMON_DIR ${CHIP_ROOT}/examples/platform/nxp/common REALPATH) +get_filename_component(EXAMPLE_PLATFORM_NXP_ZEPHYR_DIR ${CHIP_ROOT}/examples/platform/nxp/zephyr REALPATH) + +# Perform common operations like detecting extra overlays in the platform folder for the target board +# This must be called before find_package(Zephyr) +include(${CHIP_ROOT}/config/nxp/app/pre-zephyr.cmake) + +list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nxp/chip-module) +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) + +# -Wmaybe-uninitialized has too many false positives, including on std::optional +# and chip::Optional. Make it nonfatal. +# +# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635 +target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) + +project(chip-nxp-all-clusters-app-example) + +include(${CHIP_ROOT}/config/nxp/app/enable-gnu-std.cmake) +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) + +target_include_directories(app + PRIVATE + ${ALL_CLUSTERS_NXP_COMMON_DIR}/main/include + ${ALL_CLUSTERS_COMMON_DIR}/include + ${GEN_DIR}/app-common + ${GEN_DIR}/all-clusters-app + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_manager/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/icd/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_callbacks/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/factory_data/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/include +) + +target_sources(app + PRIVATE + main/main.cpp + ${ALL_CLUSTERS_NXP_COMMON_DIR}/main/AppTask.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_manager/source/CHIPDeviceManager.cpp + ${ALL_CLUSTERS_NXP_COMMON_DIR}/main/DeviceCallbacks.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_callbacks/source/CommonDeviceCallbacks.cpp + ${ALL_CLUSTERS_NXP_COMMON_DIR}/main/ZclCallbacks.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/source/AppTaskBase.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/source/AppTaskZephyr.cpp + ${EXAMPLE_PLATFORM_NXP_ZEPHYR_DIR}/factory_data/source/AppFactoryDataExample.cpp +) + +target_compile_definitions(app PUBLIC + "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/zephyr/FactoryDataProviderImpl.h\"" +) + +if(CONFIG_CHIP_OTA_REQUESTOR) + target_sources(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/source/OTARequestorInitiatorCommon.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/source/OTARequestorInitiatorZephyr.cpp + ) + target_include_directories(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/include/ + ) +endif() + +chip_configure_data_model(app + INCLUDE_SERVER + ZAP_FILE ${ALL_CLUSTERS_COMMON_DIR}/all-clusters-app.zap +) + +if(CONFIG_CHIP_LIB_SHELL) + target_compile_definitions(app PRIVATE ENABLE_CHIP_SHELL) + target_include_directories(app PRIVATE + ${CHIP_ROOT}/examples/shell/shell_common/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/include + ) + target_sources(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/source/AppCLIBase.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/source/AppCLIZephyr.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_misc.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_otcli.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_server.cpp + ) +endif() + +target_sources(app + PRIVATE + ${ALL_CLUSTERS_COMMON_DIR}/src/smco-stub.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-modes-manager.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-temperature-levels.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/bridged-actions-stub.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/fan-stub.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/air-quality-instance.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/concentration-measurement-instances.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/resource-monitoring-delegates.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/icd/source/ICDUtil.cpp +) diff --git a/examples/all-clusters-app/nxp/zephyr/Kconfig b/examples/all-clusters-app/nxp/zephyr/Kconfig new file mode 100644 index 00000000000000..748835a9d0fe6b --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/Kconfig @@ -0,0 +1,20 @@ +# +# 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. +# +mainmenu "Matter NXP All Clusters Example Application" + +rsource "../../../../config/nxp/chip-module/Kconfig.features" +rsource "../../../../config/nxp/chip-module/Kconfig.defaults" +source "Kconfig.zephyr" diff --git a/examples/all-clusters-app/nxp/zephyr/README.md b/examples/all-clusters-app/nxp/zephyr/README.md new file mode 100644 index 00000000000000..45f71ee76c077b --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/README.md @@ -0,0 +1,609 @@ +# CHIP NXP Zephyr All-clusters Application + +The all-clusters example implements a server which can be accessed by a CHIP +controller and can accept basic cluster commands. + +The example is based on +[Project CHIP](https://github.com/project-chip/connectedhomeip) and the NXP +Zephyr SDK, and provides a prototype application that demonstrates device +commissioning and different cluster control. + +
+ +- [Introduction](#introduction) +- [Building](#building) +- [Flashing and debugging](#flashing-and-debugging) +- [Factory data](#factory-data) +- [Manufacturing data](#generate-factory-data) +- [OTA Software Update](#ota-software-update) +- [Testing the example](#testing-the-example) +- [Using Matter CLI in NXP Zephyr examples](#using-matter-cli-in-nxp-zephyr-examples) + +
+ + + +## Introduction + +The Zephyr application provides a working demonstration of supported board +integration from Zephyr, built using the Project CHIP codebase and the +NXP/Zephyr SDK. + +The example supports: + +- Matter over Wi-Fi + +The supported boards are: + +- `rd_rw612_bga` + + + +## Building + +In order to build the Project CHIP example, we recommend using a Linux +distribution (the demo-application was compiled on Ubuntu 20.04). + +Prerequisites: + +- Follow instruction from [BUILDING.md](../../../../docs/guides/BUILDING.md) + to setup the Matter environment +- Follow instruction from + [Getting Started Guide](https://docs.zephyrproject.org/latest/develop/getting_started/index.html) + to setup a Zephyr workspace, however, the west init command to use is as + follows: + +```shell +$ west init zephyrproject -m https://github.com/nxp-zephyr-ear/zephyr.git --mr zephyr_rw61x_v3.6_RFP +``` + +> **Note**: Currently, supported NXP platforms in Zephyr targeting Matter are +> not available in the official Zephyr repo, you'll have to use the NXP fork +> `https://github.com/nxp-zephyr-ear/zephyr` github repo. Reach to your NXP +> contact for more details. + +Steps to build the example, targeting `rd_rw612_bga` board: + +1. Activate your Matter env: + +```shell +source /scripts/activate.sh +``` + +2. Source zephyr-env.sh: + +```shell +source /zephyr-env.sh +``` + +3. Run west build command: + +```shell +west build -b rd_rw612_bga -p +``` + +By default, a folder `build` will be created in the same folder you run the +command from. The binaries will be created in `build/zephyr` with the name +`zephyr.elf` and `zephyr.bin`. + +You can get more details on `west build` with +[Zephyr's building guide](https://docs.zephyrproject.org/latest/develop/west/build-flash-debug.html#building-west-build) + + + +## Flashing and debugging + +### Flashing without debugging + +`west` can be used to flash a target, as an example for `rd_rw612_bga` board: + +```shell +west flash -i +``` + +You can get more details on `west flash` with +[Zephyr's flashing guide](https://docs.zephyrproject.org/latest/develop/west/build-flash-debug.html#flashing-west-flash) + +> **Note**: `west flash` will not start a debug session, it will only flash and +> reset the device + +### Flash and debug + +To debug a Matter with Zephyr application, you could use several methods: + +- [MCUXpresso IDE (version >= 11.6.0)](https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-integrated-development-environment-ide:MCUXpresso-IDE) +- `west debug` + [Zephyr's debugging guide](https://docs.zephyrproject.org/latest/develop/west/build-flash-debug.html#id29) + +> **Note**: As the build provides an elf file, any compatible debugging tool can +> be used. + + + +## Factory data + +NXP Zephyr examples are not using factory data support by default. Please refer +the the section below to build with factory data. + +You may refer to `src/platform/nxp/zephyr/boards//.overlay` file +to obtain the memory region used by this partition. + +For example, the factory data partition on `rd_rw612_bga` is reserved in the +last sector of the `flexspi` flash of `RD BGA` board, at `0x1BFFF000`. + +``` +&flexspi { + status = "okay"; + + mx25u51245g: mx25u51245g@0 { + ... + factory_partition: partition@3FFF000 { + label = "factory-data"; + reg = <0x03FFF000 DT_SIZE_K(4)>; + }; + }; +}; +``` + +> **Note**: You may also refer to +> `src/platform/nxp/zephyr/boards//.overlay` file to check other +> memory partitions used by the platform, such as the file system partition +> mentioned with the `storage` label. + +### Build with factory data support + +To build the example with factory data support, you can add +`-DFILE_SUFFIX=fdata` in the west build command line. + +Example: + +```bash +west build -b rd_rw612_bga -p -- -DFILE_SUFFIX=fdata +``` + +`prj_fdata.conf` configuration file will enable `CONFIG_CHIP_FACTORY_DATA` +Kconfig so the application will load the factory data at boot. + + + +### Generate factory data + +#### Automatically (recommended) + +The factory data can be generated automatically during the build of the +application. To do so, you can use the configuration +`CONFIG_CHIP_FACTORY_DATA_BUILD=y` in `prj_fdata.conf`. + +You will have to specify the source of the certificates to be used for the +factory data. Please refer to `CHIP_FACTORY_DATA_CERT_SOURCE` Kconfig for more +info. + +> **Note**: The application demonstrates the usage of encrypted Matter factory +> data storage. Matter factory data should be encrypted using an AES 128 +> software key before flashing them to the device flash. You can encrypt the +> factory data automatically during the build by enabling +> `CHIP_ENCRYPTED_FACTORY_DATA` Kconfig. See also +> `CHIP_ENCRYPTED_FACTORY_DATA_AES128_KEY` Kconfig if you want to use a specific +> key. + +The resulting factory data will be provided along `zephyr.bin` as a binary file +named `factory_data.bin`. In order to flash it to your device, you need to know +the partition address: please refer to `factory_partition` defined in +`src/platform/nxp/zephyr/boards//.overlay`. + +#### Manually + +See +[Guide for writing manufacturing data on NXP devices](../../../../docs/guides/nxp/nxp_manufacturing_flow.md) + + + +## OTA Software Update + +See +[Guide for OTA Software Update on NXP devices using Zephyr SDK](../../../../docs/guides/nxp/nxp_zephyr_ota_software_update.md) + + + +## Testing the example + +To know how to commission a device over BLE, follow the instructions from +[chip-tool's README.md 'Commission a device over BLE'](../../../chip-tool/README.md#commission-a-device-over-ble). + + + +## Using Matter CLI in NXP Zephyr examples + +Some Matter examples for the development kits from NXP include a command-line +interface that allows access to application logs and +[Zephyr shell](https://docs.zephyrproject.org/1.13.0/subsystems/shell.html). + +Depending on the platform, the CLI console and the logs can be split on two +different interfaces. + +You may refer to `boards/.overlay` file to check how the board is +configured for the example. The binding `zephyr,console` is used to print the +logs, while the binding `zephyr,shell-uart` is used for the CLI. If the logs and +the CLI are split among two serial interfaces, you will have to open both ports. + +As an example, the Matter CLI on `rd_rw612_bga` is configured to be output on +`flexcomm3` with a baudrate of `115200`. The logs are configured to be output on +`flexcomm0` with a baudrate of `115200`. + +> **Note**: `flexcomm3` is wired to the USB `FTDI` port of the `RD BGA` board by +> default. `flexcomm0` is wired to `GPIO2` (RX) and `GPIO3` (TX). Those pins are +> accessible on `HD2` pin header. + +To access the CLI console, use a serial terminal emulator of your choice, like +Minicom or GNU Screen. Use the baud rate set to `115200`. + +### Example: Starting the CLI console with Minicom + +For example, to start using the CLI console with Minicom, run the following +command with `/dev/ttyACM0` replaced with the device node name of your +development kit: + +``` +minicom -D /dev/ttyACM0 -b 115200 +``` + +When you reboot the kit, you will see the boot logs in the console, similar to +the following messages: + +```shell +uart:~$ MAC Address: C0:95:DA:00:00:6E +... +wlan-version +wlan-mac +wlan-thread-info +wlan-net-stats +... +*** Booting Zephyr OS build zephyr-v3.4.0-187-g2ddf1330209b *** +I: Init CHIP stack +... +``` + +This means that the console is working correctly and you can start using shell +commands. For example, issuing the `kernel threads` command will print +information about all running threads: + +```shell +uart:~$ kernel threads +Scheduler: 277 since last call +Threads: + 0x20006518 CHIP + options: 0x0, priority: -1 timeout: 536896912 + state: pending + stack size 8192, unused 7256, usage 936 / 8192 (11 %) + + 0x20004ab0 SDC RX + options: 0x0, priority: -10 timeout: 536890152 + state: pending + stack size 1024, unused 848, usage 176 / 1024 (17 %) +... +``` + +## Listing all commands + +To list all available commands, use the Tab key, which is normally used for the +command completion feature. + +Pressing the Tab key in an empty command line prints the list of available +commands: + +```shell +uart:~$ + clear device help history + hwinfo kernel matter resize + retval shell +``` + +Pressing the Tab key with a command entered in the command line cycles through +available options for the given command. + +You can also run the `help` command: + +```shell +uart:~$ help +Please press the button to see all available commands. +You can also use the button to prompt or auto-complete all commands or its subcommands. +You can try to call commands with <-h> or <--help> parameter for more information. + +Shell supports following meta-keys: + Ctrl + (a key from: abcdefklnpuw) + Alt + (a key from: bf) +Please refer to shell documentation for more details. + +Available commands: + clear :Clear screen. + device :Device commands + help :Prints the help message. + history :Command history. + hwinfo :HWINFO commands + kernel :Kernel commands + matter :Matter commands + resize :Console gets terminal screen size or assumes default in case + the readout fails. It must be executed after each terminal + width change to ensure correct text display. + retval :Print return value of most recent command + shell :Useful, not Unix-like shell commands. +``` + +## Using General purpose commands + +### `kernel` command group + +#### `reboot` subcommand + +Performs either a warm or cold reset. Difference between warm and cold resets +may vary from a platform to another, but on default Cortex-M architectures, both +methods are the same, so use either one if nothing is specific to your platform. + +```shell +uart:~$ kernel reboot cold|warm +``` + +## Using Matter-specific commands + +The NXP Zephyr examples let you use several Matter-specific CLI commands. + +These commands are not available by default and to enable using them, set the +`CONFIG_CHIP_LIB_SHELL=y` Kconfig option in the `prj.conf` file of the given +example. + +Every invoked command must be preceded by the `matter` prefix. + +See the following subsections for the description of each Matter-specific +command. + +### `device` command group + +Handles a group of commands that are used to manage the device. You must use +this command together with one of the additional subcommands listed below. + +#### `factoryreset` subcommand + +Performs device factory reset that is hardware reset preceded by erasing of the +whole Matter settings stored in a non-volatile memory. + +```shell +uart:~$ matter device factoryreset +Performing factory reset ... +``` + +### `onboardingcodes` command group + +Handles a group of commands that are used to view information about device +onboarding codes. The `onboardingcodes` command takes one required parameter for +the rendezvous type, then an optional parameter for printing a specific type of +onboarding code. + +The full format of the command is as follows: + +``` +onboardingcodes none|softap|ble|onnetwork [qrcode|qrcodeurl|manualpairingcode] +``` + +#### `none` subcommand + +Prints all onboarding codes. For example: + +```shell +uart:~$ matter onboardingcodes none +QRCode: MT:W0GU2OTB00KA0648G00 +QRCodeUrl: https://project-chip.github.io/connectedhomeip/qrcode.html?data=MT%3AW0GU2OTB00KA0648G00 +ManualPairingCode: 34970112332 +``` + +#### `none qrcode` subcommand + +Prints the device onboarding QR code payload. Takes no arguments. + +```shell +uart:~$ matter onboardingcodes none qrcode +MT:W0GU2OTB00KA0648G00 +``` + +#### `none qrcodeurl` subcommand + +Prints the URL to view the device onboarding QR code in a web browser. Takes no +arguments. + +```shell +uart:~$ matter onboardingcodes none qrcodeurl +https://project-chip.github.io/connectedhomeip/qrcode.html?data=MT%3AW0GU2OTB00KA0648G00 +``` + +#### `none manualpairingcode` subcommand + +Prints the pairing code for the manual onboarding of a device. Takes no +arguments. + +```shell +uart:~$ matter onboardingcodes none manualpairingcode +34970112332 +``` + +### `config` command group + +Handles a group of commands that are used to view device configuration +information. You can use this command without any subcommand to print all +available configuration data or to add a specific subcommand. + +```shell +uart:~$ matter config +VendorId: 65521 (0xFFF1) +ProductId: 32768 (0x8000) +HardwareVersion: 1 (0x1) +FabricId: +PinCode: 020202021 +Discriminator: f00 +DeviceId: +``` + +The `config` command can also take the subcommands listed below. + +#### `pincode` subcommand + +Prints the PIN code for device setup. Takes no arguments. + +```shell +uart:~$ matter config pincode +020202021 +``` + +#### `discriminator` subcommand + +Prints the device setup discriminator. Takes no arguments. + +```shell +uart:~$ matter config discriminator +f00 +``` + +#### `vendorid` subcommand + +Prints the vendor ID of the device. Takes no arguments. + +```shell +uart:~$ matter config vendorid +65521 (0xFFFF1) +``` + +#### `productid` subcommand + +Prints the product ID of the device. Takes no arguments. + +```shell +uart:~$ matter config productid +32768 (0x8000) +``` + +#### `hardwarever` subcommand + +Prints the hardware version of the device. Takes no arguments. + +```shell +uart:~$ matter config hardwarever +1 (0x1) +``` + +#### `deviceid` subcommand + +Prints the device identifier. Takes no arguments. + +#### `fabricid` subcommand + +Prints the fabric identifier. Takes no arguments. + +### `ble` command group + +Handles a group of commands that are used to control the device Bluetooth LE +transport state. You must use this command together with one of the additional +subcommands listed below. + +#### `help` subcommand + +Prints help information about the `ble` command group. + +```shell +uart:~$ matter ble help + help Usage: ble + adv Enable or disable advertisement. Usage: ble adv +``` + +#### `adv start` subcommand + +Enables Bluetooth LE advertising. + +```shell +uart:~$ matter ble adv start +Starting BLE advertising +``` + +#### `adv stop` subcommand + +Disables Bluetooth LE advertising. + +```shell +uart:~$ matter ble adv stop +Stopping BLE advertising +``` + +#### `adv status` subcommand + +Prints the information about the current Bluetooth LE advertising status. + +```shell +uart:~$ matter ble adv state +BLE advertising is disabled + +``` + +### `dns` command group + +Handles a group of commands that are used to trigger performing DNS queries. You +must use this command together with one of the additional subcommands listed +below. + +#### `browse` subcommand + +Browses for DNS services of `_matterc_udp` type and prints the received +response. Takes no argument. + +```shell +uart:~$ matter dns browse +Browsing ... +DNS browse succeeded: + Hostname: 0E824F0CA6DE309C + Vendor ID: 9050 + Product ID: 20043 + Long discriminator: 3840 + Device type: 0 + Device name: + Commissioning mode: 0 + IP addresses: + fd08:b65e:db8e:f9c7:2cc2:2043:1366:3b31 +``` + +#### `resolve` subcommand + +Resolves the specified Matter node service given by the _fabric-id_ and +_node-id_. + +```shell +uart:~$ matter dns resolve fabric-id node-id +Resolving ... +DNS resolve for 000000014A77CBB3-0000000000BC5C01 succeeded: + IP address: fd08:b65e:db8e:f9c7:8052:1a8e:4dd4:e1f3 + Port: 5540 +``` + +### `stat` command group + +Handles a group of commands that are used to get and reset the peak usage of +critical system resources used by Matter. These commands are only available when +the `CONFIG_CHIP_STATISTICS=y` Kconfig option is set. + +#### `peak` subcommand + +Prints the peak usage of system resources. + +```shell +uart:~$ matter stat peak +Packet Buffers: 1 +Timers: 2 +TCP endpoints: 0 +UDP endpoints: 1 +Exchange contexts: 0 +Unsolicited message handlers: 5 +Platform events: 2 +``` + +#### `reset` subcommand + +Resets the peak usage of system resources. + +```shell +uart:~$ matter stat reset +``` diff --git a/examples/all-clusters-app/nxp/zephyr/boards/rd_rw612_bga.overlay b/examples/all-clusters-app/nxp/zephyr/boards/rd_rw612_bga.overlay new file mode 100644 index 00000000000000..86bb20739527cd --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/boards/rd_rw612_bga.overlay @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023-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. + */ + +/ { + chosen { + zephyr,console = &flexcomm0; + zephyr,shell-uart = &flexcomm3; + }; +}; + +&flexcomm0 { + compatible = "nxp,lpc-usart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm0_usart>; + pinctrl-names = "default"; +}; + +&flexcomm3 { + compatible = "nxp,lpc-usart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm3_usart>; + pinctrl-names = "default"; +}; diff --git a/examples/all-clusters-app/nxp/zephyr/boards/rd_rw612_bga_fdata.conf b/examples/all-clusters-app/nxp/zephyr/boards/rd_rw612_bga_fdata.conf new file mode 100644 index 00000000000000..73d139c3948d95 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/boards/rd_rw612_bga_fdata.conf @@ -0,0 +1,23 @@ +# +# Copyright (c) 2023-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. +# + +CONFIG_SETTINGS_NVS_SECTOR_COUNT=16 + +# 0xA226 +CONFIG_CHIP_DEVICE_PRODUCT_ID=41510 +CONFIG_CHIP_DEVICE_PRODUCT_URL="https://www.nxp.com/products/wireless-connectivity/wi-fi-plus-bluetooth-plus-802-15-4/wireless-mcu-with-integrated-tri-radio-1x1-wi-fi-6-plus-bluetooth-low-energy-5-3-802-15-4:RW612" +CONFIG_CHIP_DEVICE_PRODUCT_LABEL="RW612" +CONFIG_CHIP_DEVICE_PART_NUMBER="RW612" diff --git a/examples/all-clusters-app/nxp/zephyr/main/include/CHIPProjectConfig.h b/examples/all-clusters-app/nxp/zephyr/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..f6c88ccef18162 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/main/include/CHIPProjectConfig.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023-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. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +// All clusters app has 3 group endpoints. This needs to defined here so that +// CHIP_CONFIG_MAX_GROUPS_PER_FABRIC is properly configured. +#define CHIP_CONFIG_MAX_GROUP_ENDPOINTS_PER_FABRIC 3 diff --git a/examples/all-clusters-app/nxp/zephyr/main/main.cpp b/examples/all-clusters-app/nxp/zephyr/main/main.cpp new file mode 100644 index 00000000000000..9be47dfe0a95d8 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/main/main.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023-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 "AppTask.h" + +#include + +LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); + +using namespace ::chip; + +int main() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + if (err == CHIP_NO_ERROR) + { + err = chip::NXP::App::GetAppTask().Start(); + } + + LOG_ERR("Exited with code %" CHIP_ERROR_FORMAT, err.Format()); + return err == CHIP_NO_ERROR ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/all-clusters-app/nxp/zephyr/prj.conf b/examples/all-clusters-app/nxp/zephyr/prj.conf new file mode 100644 index 00000000000000..936bc5984f4f35 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/prj.conf @@ -0,0 +1,59 @@ +# +# Copyright (c) 2023-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. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_STD_CPP17=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y +# CHIP PID: 32769 == 0x8001 (all-clusters-app) +CONFIG_CHIP_DEVICE_PRODUCT_ID=32769 +CONFIG_CHIP_DEVICE_PRODUCT_NAME="All Clusters" +CONFIG_CHIP_DEVICE_DISCRIMINATOR=0x800 + +# Enable MbedTLS PSA - heavily experimental, not thread safe yet +# CONFIG_CHIP_CRYPTO_PSA=y + +# Bluetooth overrides +CONFIG_BT_DEVICE_NAME="NXPAllClusters" + +# Additional configs for debbugging experience. +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y + +CONFIG_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_THREAD_INFO=y +# use this config if stepping during debug session is not consistent +# CONFIG_NO_OPTIMIZATIONS=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_ASSERT=y +# by default west will generate the full assembly output, which can take several minutes when binaries are large +CONFIG_OUTPUT_DISASSEMBLY=n +# embedded thread analyzer with thread statistics (stack usage, cpu usage...) +# CONFIG_THREAD_ANALYZER=y +# CONFIG_THREAD_ANALYZER_USE_PRINTK=y +# CONFIG_THREAD_ANALYZER_AUTO=y + +# enable Matter CLI +CONFIG_CHIP_LIB_SHELL=y +# enable NET commands if desired +#CONFIG_NET_SHELL=y +CONFIG_CHIP_STATISTICS=y diff --git a/examples/all-clusters-app/nxp/zephyr/prj_fdata.conf b/examples/all-clusters-app/nxp/zephyr/prj_fdata.conf new file mode 100644 index 00000000000000..a82618a5f46078 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/prj_fdata.conf @@ -0,0 +1,80 @@ +# +# Copyright (c) 2023-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. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_STD_CPP17=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable MbedTLS PSA - heavily experimental, not thread safe yet +# CONFIG_CHIP_CRYPTO_PSA=y + +# Bluetooth overrides +CONFIG_BT_DEVICE_NAME="NXPAllClusters" + +# enable Matter CLI +CONFIG_CHIP_LIB_SHELL=y +CONFIG_CHIP_STATISTICS=y + +# Factory data configuration +CONFIG_CHIP_DEVICE_VENDOR_ID=4151 +CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xA00 +CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE=14014 +CONFIG_CHIP_DEVICE_PRODUCT_NAME="All Clusters" +CONFIG_CHIP_DEVICE_TYPE=115 +CONFIG_CHIP_DEVICE_MANUFACTURING_DATE="2023-01-01" +CONFIG_CHIP_DEVICE_SERIAL_NUMBER="12345678" +CONFIG_CHIP_DEVICE_PRODUCT_COLOR="Green" +CONFIG_CHIP_DEVICE_PRODUCT_FINISH="Matte" + +# Use factory data provider for device info +CONFIG_CHIP_FACTORY_DATA=y +# Generate factor data raw binary during the build process +# CONFIG_CHIP_FACTORY_DATA_BUILD=y +# Generate test certificates for factory data during the build process +# CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED=y +# Spake2p verifier will be generated during factory data generation +# CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER=y + +# Example of using pre-generated certificates +# CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_USER=y +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_CD_CERT="/Chip-Test-CD-1037-A226.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_CERT="/Chip-DAC-NXP-1037-A226-Cert.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_KEY="/Chip-DAC-NXP-1037-A226-Key.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_PAI_CERT="/Chip-PAI-NXP-1037-A226-Cert.der" + +# Additional configs for debbugging experience. +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y + +CONFIG_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_THREAD_INFO=y +# use this config if stepping during debug session is not consistent +# CONFIG_NO_OPTIMIZATIONS=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_ASSERT=y +# by default west will generate the full assembly output, which can take several minutes when binaries are large +CONFIG_OUTPUT_DISASSEMBLY=n +# embedded thread analyzer with thread statistics (stack usage, cpu usage...) +# CONFIG_THREAD_ANALYZER=y +# CONFIG_THREAD_ANALYZER_USE_PRINTK=y +# CONFIG_THREAD_ANALYZER_AUTO=y diff --git a/examples/all-clusters-app/nxp/zephyr/prj_ota.conf b/examples/all-clusters-app/nxp/zephyr/prj_ota.conf new file mode 100644 index 00000000000000..bdc65e94fabf70 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/prj_ota.conf @@ -0,0 +1,31 @@ +# +# 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. +# + +# Options needed for OTA are located on this file +# This file should contain only options specific for this sample +# or overrides the default ones. + +CONFIG_CHIP_OTA_REQUESTOR=y + +# To generate an OTA image based on the application +CONFIG_CHIP_OTA_IMAGE_BUILD=y + +# By default, MCUBOOT bootloader uses a signature key provided in their repository. +# Change the key to the appropriate one. +# Note: You need to use the same signature key used by MCUBOOT, i.e BOOT_SIGNATURE_KEY_FILE. +# Default CONFIG_BOOT_SIGNATURE_KEY_FILE is defined in config/nxp/app/bootloader.conf +CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="./bootloader/mcuboot/root-rsa-2048.pem" diff --git a/examples/all-clusters-app/nxp/zephyr/third_party/connectedhomeip b/examples/all-clusters-app/nxp/zephyr/third_party/connectedhomeip new file mode 120000 index 00000000000000..3efed95be5dbe9 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../ \ No newline at end of file diff --git a/examples/all-clusters-minimal-app/esp32/sdkconfig.defaults.esp32c2 b/examples/all-clusters-minimal-app/esp32/sdkconfig.defaults.esp32c2 index 6cb90db4f55b9d..200dc5825bc2e2 100644 --- a/examples/all-clusters-minimal-app/esp32/sdkconfig.defaults.esp32c2 +++ b/examples/all-clusters-minimal-app/esp32/sdkconfig.defaults.esp32c2 @@ -17,3 +17,6 @@ CONFIG_BT_NIMBLE_ROLE_OBSERVER=n CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=4 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=8 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=16 + +# Event Queue Size +CONFIG_MAX_EVENT_QUEUE_SIZE=25 diff --git a/examples/chip-tool/commands/common/RemoteDataModelLogger.cpp b/examples/chip-tool/commands/common/RemoteDataModelLogger.cpp index 9e4f29c5534757..294673512882b3 100644 --- a/examples/chip-tool/commands/common/RemoteDataModelLogger.cpp +++ b/examples/chip-tool/commands/common/RemoteDataModelLogger.cpp @@ -241,7 +241,8 @@ CHIP_ERROR LogDiscoveredNodeData(const chip::Dnssd::CommissionNodeData & nodeDat value["rotatingIdLen"] = static_cast(commissionData.rotatingIdLen); value["pairingHint"] = commissionData.pairingHint; value["pairingInstruction"] = commissionData.pairingInstruction; - value["supportsTcp"] = resolutionData.supportsTcp; + value["supportsTcpClient"] = resolutionData.supportsTcpClient; + value["supportsTcpServer"] = resolutionData.supportsTcpServer; value["port"] = resolutionData.port; value["numIPs"] = static_cast(resolutionData.numIPs); diff --git a/examples/chip-tool/commands/discover/Commands.h b/examples/chip-tool/commands/discover/Commands.h index e7a59dbaee9110..d308d4ab75b430 100644 --- a/examples/chip-tool/commands/discover/Commands.h +++ b/examples/chip-tool/commands/discover/Commands.h @@ -53,7 +53,8 @@ class Resolve : public DiscoverCommand, public chip::AddressResolve::NodeListene result.mrpRemoteConfig.mIdleRetransTimeout.count()); ChipLogProgress(chipTool, " MRP retry interval (active): %" PRIu32 "ms", result.mrpRemoteConfig.mActiveRetransTimeout.count()); - ChipLogProgress(chipTool, " Supports TCP: %s", result.supportsTcp ? "yes" : "no"); + ChipLogProgress(chipTool, " Supports TCP Client: %s", result.supportsTcpClient ? "yes" : "no"); + ChipLogProgress(chipTool, " Supports TCP Server: %s", result.supportsTcpServer ? "yes" : "no"); ChipLogProgress(chipTool, " ICD is operating as: %s", result.isICDOperatingAsLIT ? "LIT" : "SIT"); SetCommandExitStatus(CHIP_NO_ERROR); } diff --git a/examples/common/m5stack-tft/repo b/examples/common/m5stack-tft/repo index d99f5ef8df180a..a6299b6c7c0b2e 160000 --- a/examples/common/m5stack-tft/repo +++ b/examples/common/m5stack-tft/repo @@ -1 +1 @@ -Subproject commit d99f5ef8df180ab34b3d9fff6888d5bede7665c5 +Subproject commit a6299b6c7c0b2e3eb62fa08ee4bf7155c39bad1f diff --git a/examples/common/tracing/decoder/logging/ToCertificateString.cpp b/examples/common/tracing/decoder/logging/ToCertificateString.cpp index 423544a9cc2a0c..1abd27ef788c59 100644 --- a/examples/common/tracing/decoder/logging/ToCertificateString.cpp +++ b/examples/common/tracing/decoder/logging/ToCertificateString.cpp @@ -35,7 +35,7 @@ const char * ToCertificate(const chip::ByteSpan & source, chip::MutableCharSpan { // Reset the buffer memset(destination.data(), '\0', destination.size()); - + int snprintf_len = 0; if (source.size() == 0) { return destination.data(); @@ -70,7 +70,8 @@ const char * ToCertificate(const chip::ByteSpan & source, chip::MutableCharSpan ChipLogError(DataManagement, "Certificate size is greater than 400 bytes"); } - snprintf(destination.data(), destination.size(), "%s", str.Get()); + snprintf_len = snprintf(destination.data(), destination.size(), "%s", str.Get()); + VerifyOrExit(snprintf_len >= 0, ChipLogError(DataManagement, "Failed to write certificate");); } else { @@ -83,15 +84,23 @@ const char * ToCertificate(const chip::ByteSpan & source, chip::MutableCharSpan size_t inIndex = 0; size_t outIndex = strlen(header) + 1; - snprintf(destination.data(), destination.size(), "%s\n", header); + snprintf_len = snprintf(destination.data(), destination.size(), "%s\n", header); + VerifyOrExit(snprintf_len >= 0, ChipLogError(DataManagement, "Failed to write header");); for (; inIndex < base64DataLen; inIndex += 64) { - auto charsPrinted = snprintf(&destination.data()[outIndex], destination.size() - outIndex, "%.64s\n", &str[inIndex]); - outIndex += static_cast(charsPrinted); + snprintf_len = snprintf(&destination.data()[outIndex], destination.size() - outIndex, "%.64s\n", &str[inIndex]); + VerifyOrExit(snprintf_len >= 0, ChipLogError(DataManagement, "Failed to write certificate");); + + outIndex += static_cast(snprintf_len); } - snprintf(&destination.data()[outIndex], destination.size() - outIndex, "%s", footer); + snprintf_len = snprintf(&destination.data()[outIndex], destination.size() - outIndex, "%s", footer); + VerifyOrExit(snprintf_len >= 0, ChipLogError(DataManagement, "Failed to write footer");); + } +exit: + if (snprintf_len < 0) + { + memset(destination.data(), '\0', destination.size()); } - return destination.data(); } diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/README.md b/examples/contact-sensor-app/nxp/k32w/k32w0/README.md index ae519c9808c882..ac418ecbd4aa77 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/README.md +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/README.md @@ -730,9 +730,14 @@ Please see more in the Here is an example that generates an OTA image with application update TLV: ``` -./scripts/tools/nxp/ota/ota_image_tool.py create -v 0xDEAD -p 0xBEEF -vn 42021 -vs "1.0" -da sha256 --app-input-file chip-k32w0x-contact-example.bin chip-k32w0x-contact-example.ota +./scripts/tools/nxp/ota/ota_image_tool.py create -v 0xDEAD -p 0xBEEF -vn 2 -vs "2.0" -da sha256 --enc_enable --input_ota_key "1234567890ABCDEFA1B2C3D4E5F6F1B4" --app-input-file chip-k32w0x-contact-example.bin chip-k32w0x-contact-example.ota ``` +Please note the two options `--enc_enable` and `--input_ota_key`, which are +mandatory when `chip_with_ota_encryption=1`. The value of `--input_ota_key` must +match the value of `chip_with_ota_key`. See `args.gni` for the default gn +configuration. + A note regarding OTA image header version (`-vn` option). An application binary has its own software version, given by `CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION` (`42020` by default), which can be diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h index 7dc5b848e22324..6cb580ded9c35f 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h +++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h @@ -39,7 +39,7 @@ class CHIPCommandBridge : public Command { { AddArgument("commissioner-name", &mCommissionerName); AddArgument("commissioner-nodeId", 0, UINT64_MAX, &mCommissionerNodeId, - "Sets the commisser node ID of the given " + "Sets the commissioner node ID of the given " "commissioner-name. Interactive mode will only set a single commissioner on the inital command. " "The commissioner node ID will be persisted until a different one is specified."); AddArgument("paa-trust-store-path", &mPaaTrustStorePath, diff --git a/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm b/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm index 9723199ed007a4..52f0fd4bb10a17 100644 --- a/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm +++ b/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm @@ -36,7 +36,7 @@ - (void)controller:(MTRDeviceController *)controller statusUpdate:(MTRCommission ChipLogError(chipTool, "MTRCommissioningStatusDiscoveringMoreDevices: This should not happen."); break; case MTRCommissioningStatusUnknown: - ChipLogError(chipTool, "Uknown Pairing Status"); + ChipLogError(chipTool, "Unknown Pairing Status"); break; } } diff --git a/examples/energy-management-app/energy-management-common/energy-management-app.matter b/examples/energy-management-app/energy-management-common/energy-management-app.matter index 3035f377a13475..f34ffd80cdf87b 100644 --- a/examples/energy-management-app/energy-management-common/energy-management-app.matter +++ b/examples/energy-management-app/energy-management-common/energy-management-app.matter @@ -1651,7 +1651,7 @@ provisional cluster DeviceEnergyManagement = 152 { /** Electric Vehicle Supply Equipment (EVSE) is equipment used to charge an Electric Vehicle (EV) or Plug-In Hybrid Electric Vehicle. This cluster provides an interface to the functionality of Electric Vehicle Supply Equipment (EVSE) management. */ cluster EnergyEvse = 153 { - revision 2; + revision 4; enum EnergyTransferStoppedReasonEnum : enum8 { kEVStopped = 0; @@ -1695,6 +1695,7 @@ cluster EnergyEvse = 153 { kDischargingEnabled = 2; kDisabledError = 3; kDisabledDiagnostics = 4; + kEnabled = 5; } bitmap Feature : bitmap32 { @@ -1742,6 +1743,7 @@ cluster EnergyEvse = 153 { int32u sessionID = 0; StateEnum state = 1; amperage_ma maximumCurrent = 2; + optional amperage_ma maximumDischargeCurrent = 3; } info event EnergyTransferStopped = 3 { @@ -1749,6 +1751,7 @@ cluster EnergyEvse = 153 { StateEnum state = 1; EnergyTransferStoppedReasonEnum reason = 2; energy_mwh energyTransferred = 4; + optional energy_mwh energyDischarged = 5; } critical event Fault = 4 { @@ -1813,15 +1816,15 @@ cluster EnergyEvse = 153 { /** Allows a client to disable the EVSE from charging and discharging. */ timed command Disable(): DefaultSuccess = 1; - /** Allows a client to enable the EVSE to charge an EV. */ + /** This command allows a client to enable the EVSE to charge an EV, */ timed command EnableCharging(EnableChargingRequest): DefaultSuccess = 2; - /** Allows a client to enable the EVSE to discharge an EV. */ + /** Upon receipt, this SHALL allow a client to enable the discharge of an EV, */ timed command EnableDischarging(EnableDischargingRequest): DefaultSuccess = 3; /** Allows a client to put the EVSE into a self-diagnostics mode. */ timed command StartDiagnostics(): DefaultSuccess = 4; /** Allows a client to set the user specified charging targets. */ timed command SetTargets(SetTargetsRequest): DefaultSuccess = 5; - /** Allows a client to retrieve the user specified charging targets. */ + /** Allows a client to retrieve the current set of charging targets. */ timed command GetTargets(): GetTargetsResponse = 6; /** Allows a client to clear all stored charging targets. */ timed command ClearTargets(): DefaultSuccess = 7; diff --git a/examples/energy-management-app/esp32/sdkconfig.defaults.esp32c2 b/examples/energy-management-app/esp32/sdkconfig.defaults.esp32c2 index 5e5d596cacb673..2347f73ec8cc6c 100644 --- a/examples/energy-management-app/esp32/sdkconfig.defaults.esp32c2 +++ b/examples/energy-management-app/esp32/sdkconfig.defaults.esp32c2 @@ -18,5 +18,8 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=4 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=8 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=16 +# Event Queue Size +CONFIG_MAX_EVENT_QUEUE_SIZE=25 + # Enable HKDF in mbedtls CONFIG_MBEDTLS_HKDF_C=y diff --git a/examples/fabric-admin/commands/common/RemoteDataModelLogger.cpp b/examples/fabric-admin/commands/common/RemoteDataModelLogger.cpp index c8e9d5a5450703..6334d42506d53f 100644 --- a/examples/fabric-admin/commands/common/RemoteDataModelLogger.cpp +++ b/examples/fabric-admin/commands/common/RemoteDataModelLogger.cpp @@ -241,7 +241,8 @@ CHIP_ERROR LogDiscoveredNodeData(const chip::Dnssd::CommissionNodeData & nodeDat value["rotatingIdLen"] = static_cast(commissionData.rotatingIdLen); value["pairingHint"] = commissionData.pairingHint; value["pairingInstruction"] = commissionData.pairingInstruction; - value["supportsTcp"] = resolutionData.supportsTcp; + value["supportsTcpClient"] = resolutionData.supportsTcpClient; + value["supportsTcpServer"] = resolutionData.supportsTcpServer; value["port"] = resolutionData.port; value["numIPs"] = static_cast(resolutionData.numIPs); diff --git a/examples/fabric-admin/rpc/RpcClient.cpp b/examples/fabric-admin/rpc/RpcClient.cpp index f03c4f3f699838..40d2e8ba09aa2e 100644 --- a/examples/fabric-admin/rpc/RpcClient.cpp +++ b/examples/fabric-admin/rpc/RpcClient.cpp @@ -19,9 +19,11 @@ #include "RpcClient.h" #include "RpcClientProcessor.h" +#include +#include +#include #include #include -#include #include "fabric_bridge_service/fabric_bridge_service.rpc.pb.h" #include "pw_assert/check.h" @@ -36,6 +38,7 @@ using namespace chip; namespace { // Constants +constexpr uint32_t kRpcTimeoutMs = 1000; constexpr uint32_t kDefaultChannelId = 1; // Fabric Bridge Client @@ -43,9 +46,37 @@ rpc::pw_rpc::nanopb::FabricBridge::Client fabricBridgeClient(rpc::client::GetDef pw::rpc::NanopbUnaryReceiver<::pw_protobuf_Empty> addSynchronizedDeviceCall; pw::rpc::NanopbUnaryReceiver<::pw_protobuf_Empty> removeSynchronizedDeviceCall; +std::mutex responseMutex; +std::condition_variable responseCv; +bool responseReceived = false; +CHIP_ERROR responseError = CHIP_NO_ERROR; + +template +CHIP_ERROR WaitForResponse(CallType & call) +{ + std::unique_lock lock(responseMutex); + responseReceived = false; + responseError = CHIP_NO_ERROR; + + if (responseCv.wait_for(lock, std::chrono::milliseconds(kRpcTimeoutMs), [] { return responseReceived; })) + { + return responseError; + } + else + { + fprintf(stderr, "RPC Response timed out!"); + return CHIP_ERROR_TIMEOUT; + } +} + // Callback function to be called when the RPC response is received void OnAddDeviceResponseCompleted(const pw_protobuf_Empty & response, pw::Status status) { + std::lock_guard lock(responseMutex); + responseReceived = true; + responseError = status.ok() ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + responseCv.notify_one(); + if (status.ok()) { ChipLogProgress(NotSpecified, "AddSynchronizedDevice RPC call succeeded!"); @@ -59,6 +90,11 @@ void OnAddDeviceResponseCompleted(const pw_protobuf_Empty & response, pw::Status // Callback function to be called when the RPC response is received void OnRemoveDeviceResponseCompleted(const pw_protobuf_Empty & response, pw::Status status) { + std::lock_guard lock(responseMutex); + responseReceived = true; + responseError = status.ok() ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + responseCv.notify_one(); + if (status.ok()) { ChipLogProgress(NotSpecified, "RemoveSynchronizedDevice RPC call succeeded!"); @@ -101,7 +137,7 @@ CHIP_ERROR AddSynchronizedDevice(chip::NodeId nodeId) return CHIP_ERROR_INTERNAL; } - return CHIP_NO_ERROR; + return WaitForResponse(addSynchronizedDeviceCall); } CHIP_ERROR RemoveSynchronizedDevice(chip::NodeId nodeId) @@ -128,5 +164,5 @@ CHIP_ERROR RemoveSynchronizedDevice(chip::NodeId nodeId) return CHIP_ERROR_INTERNAL; } - return CHIP_NO_ERROR; + return WaitForResponse(removeSynchronizedDeviceCall); } diff --git a/examples/fabric-admin/rpc/RpcClient.h b/examples/fabric-admin/rpc/RpcClient.h index eb28c19bee7d3e..a1754b3846d508 100644 --- a/examples/fabric-admin/rpc/RpcClient.h +++ b/examples/fabric-admin/rpc/RpcClient.h @@ -41,7 +41,7 @@ CHIP_ERROR InitRpcClient(uint16_t rpcServerPort); * * @param nodeId The Node ID of the device to be added. * @return CHIP_ERROR An error code indicating the success or failure of the operation. - * - CHIP_NO_ERROR: The RPC command was successfully sent. + * - CHIP_NO_ERROR: The RPC command was successfully processed. * - CHIP_ERROR_BUSY: Another operation is currently in progress. * - CHIP_ERROR_INTERNAL: An internal error occurred while activating the RPC call. */ @@ -56,7 +56,7 @@ CHIP_ERROR AddSynchronizedDevice(chip::NodeId nodeId); * * @param nodeId The Node ID of the device to be removed. * @return CHIP_ERROR An error code indicating the success or failure of the operation. - * - CHIP_NO_ERROR: The RPC command was successfully sent. + * - CHIP_NO_ERROR: The RPC command was successfully processed. * - CHIP_ERROR_BUSY: Another operation is currently in progress. * - CHIP_ERROR_INTERNAL: An internal error occurred while activating the RPC call. */ diff --git a/examples/fabric-admin/scripts/run_fabric_sink.sh b/examples/fabric-admin/scripts/run_fabric_sink.sh new file mode 100755 index 00000000000000..3013965479268a --- /dev/null +++ b/examples/fabric-admin/scripts/run_fabric_sink.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# Default paths +DEFAULT_CHOICES=( + "./fabric-admin" + "out/debug/standalone/fabric-admin" + "out/linux-x64-fabric-admin/fabric-admin" + "out/darwin-arm64-fabric-admin/fabric-admin" +) +FABRIC_ADMIN_LOG="/tmp/fabric_admin.log" +FABRIC_ADMIN_PATH="" + +# Function to find fabric-admin binary +find_fabric_admin() { + local choices=("$@") + for path in "${choices[@]}"; do + if [[ -e "$path" ]]; then + echo "$path" + return 0 + fi + done + return 1 +} + +# Parse arguments +VERBOSE=false +SPECIFIED_PATH="" + +for arg in "$@"; do + case $arg in + --verbose) + VERBOSE=true + ;; + --path=*) + SPECIFIED_PATH="${arg#*=}" + ;; + esac +done + +# Use specified path if provided +if [[ -n "$SPECIFIED_PATH" ]]; then + if [[ -e "$SPECIFIED_PATH" ]]; then + FABRIC_ADMIN_PATH="$SPECIFIED_PATH" + else + echo >&2 "Specified path does not exist: $SPECIFIED_PATH" + exit 1 + fi +else + FABRIC_ADMIN_PATH=$(find_fabric_admin "${DEFAULT_CHOICES[@]}") + if [[ $? -ne 0 ]]; then + echo >&2 "Could not find the fabric-admin binary" + exit 1 + fi +fi + +echo "PATH IS: $FABRIC_ADMIN_PATH" + +# Kill fabric-admin if it is running +echo "Checking for running fabric-admin process..." +fabric_admin_pid=$(pgrep -f "$FABRIC_ADMIN_PATH") +if [[ -n "$fabric_admin_pid" ]]; then + echo "Found fabric-admin with PID $fabric_admin_pid, attempting to kill..." + kill -9 "$fabric_admin_pid" + echo "Killed fabric-admin with PID $fabric_admin_pid" +fi + +# Remove /tmp/chip_* files and directories +echo "Removing /tmp/chip_* files and directories..." +sudo rm -rf /tmp/chip_* +echo "Removed /tmp/chip_* files and directories" + +# Start fabric-admin with or without log file path based on --verbose option +echo "Starting fabric-admin..." +if [ "$VERBOSE" = true ]; then + "$FABRIC_ADMIN_PATH" +else + "$FABRIC_ADMIN_PATH" --log-file-path "$FABRIC_ADMIN_LOG" +fi diff --git a/examples/fabric-admin/scripts/run_fabric_source.sh b/examples/fabric-admin/scripts/run_fabric_source.sh new file mode 100755 index 00000000000000..95df7a135bb596 --- /dev/null +++ b/examples/fabric-admin/scripts/run_fabric_source.sh @@ -0,0 +1,116 @@ +#!/bin/bash + +# Get the path to the current script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Default paths +DEFAULT_ADMIN_CHOICES=( + "./fabric-admin" + "out/debug/standalone/fabric-admin" + "out/linux-x64-fabric-admin/fabric-admin" + "out/darwin-arm64-fabric-admin/fabric-admin" +) +DEFAULT_BRIDGE_CHOICES=( + "./fabric-bridge-app" + "out/debug/standalone/fabric-bridge-app" + "out/linux-x64-fabric-bridge-app/fabric-bridge-app" + "out/darwin-arm64-fabric-bridge-app/fabric-bridge-app" +) +FABRIC_ADMIN_LOG="/tmp/fabric_admin.log" +FABRIC_BRIDGE_APP_LOG="/tmp/fabric_bridge_app.log" +FABRIC_ADMIN_PATH="" +FABRIC_BRIDGE_APP_PATH="" + +# Function to find a binary +find_binary() { + local choices=("$@") + for path in "${choices[@]}"; do + if [[ -e "$path" ]]; then + echo "$path" + return 0 + fi + done + return 1 +} + +# Parse arguments +VERBOSE=false +SPECIFIED_ADMIN_PATH="" +SPECIFIED_BRIDGE_PATH="" + +for arg in "$@"; do + case $arg in + --verbose) + VERBOSE=true + ;; + --admin-path=*) + SPECIFIED_ADMIN_PATH="${arg#*=}" + ;; + --bridge-path=*) + SPECIFIED_BRIDGE_PATH="${arg#*=}" + ;; + esac +done + +# Use specified paths if provided +if [[ -n "$SPECIFIED_ADMIN_PATH" ]]; then + if [[ -e "$SPECIFIED_ADMIN_PATH" ]]; then + FABRIC_ADMIN_PATH="$SPECIFIED_ADMIN_PATH" + else + echo >&2 "Specified admin path does not exist: $SPECIFIED_ADMIN_PATH" + exit 1 + fi +else + FABRIC_ADMIN_PATH=$(find_binary "${DEFAULT_ADMIN_CHOICES[@]}") + if [[ $? -ne 0 ]]; then + echo >&2 "Could not find the fabric-admin binary" + exit 1 + fi +fi + +if [[ -n "$SPECIFIED_BRIDGE_PATH" ]]; then + if [[ -e "$SPECIFIED_BRIDGE_PATH" ]]; then + FABRIC_BRIDGE_APP_PATH="$SPECIFIED_BRIDGE_PATH" + else + echo >&2 "Specified bridge path does not exist: $SPECIFIED_BRIDGE_PATH" + exit 1 + fi +else + FABRIC_BRIDGE_APP_PATH=$(find_binary "${DEFAULT_BRIDGE_CHOICES[@]}") + if [[ $? -ne 0 ]]; then + echo >&2 "Could not find the fabric-bridge-app binary" + exit 1 + fi +fi + +echo "Admin path: $FABRIC_ADMIN_PATH" +echo "Bridge path: $FABRIC_BRIDGE_APP_PATH" + +# Determine the path to stop_fabric_source.sh based on the location of run_fabric_source.sh +RUN_FABRIC_SOURCE_PATH=$(find_binary "$SCRIPT_DIR/run_fabric_source.sh") +if [[ $? -ne 0 ]]; then + echo >&2 "Could not find the run_fabric_source.sh script" + exit 1 +fi +STOP_FABRIC_SOURCE_PATH="${RUN_FABRIC_SOURCE_PATH/run_fabric_source/stop_fabric_source}" + +# Stop any running instances and clean up +if [[ -e "$STOP_FABRIC_SOURCE_PATH" ]]; then + "$STOP_FABRIC_SOURCE_PATH" +else + echo >&2 "Could not find the stop_fabric_source.sh script" + exit 1 +fi + +# Start fabric-bridge-app if available and redirect its output to /dev/null +if [ -f "$FABRIC_BRIDGE_APP_PATH" ]; then + "$FABRIC_BRIDGE_APP_PATH" >"$FABRIC_BRIDGE_APP_LOG" 2>&1 & + echo "Started fabric-bridge-app" +fi + +# Start fabric-admin with or without log file path based on --verbose option +if [ "$VERBOSE" = true ]; then + "$FABRIC_ADMIN_PATH" +else + "$FABRIC_ADMIN_PATH" --log-file-path "$FABRIC_ADMIN_LOG" +fi diff --git a/examples/fabric-admin/scripts/stop_fabric_source.sh b/examples/fabric-admin/scripts/stop_fabric_source.sh new file mode 100755 index 00000000000000..85fff9e3a878cc --- /dev/null +++ b/examples/fabric-admin/scripts/stop_fabric_source.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +FABRIC_ADMIN_PATH="/fabric-admin" +FABRIC_BRIDGE_APP_PATH="/fabric-bridge-app" + +# Kill fabric-admin if it is running +fabric_admin_pid=$(pgrep -f "$FABRIC_ADMIN_PATH") +if [ ! -z "$fabric_admin_pid" ]; then + kill -9 "$fabric_admin_pid" + echo "Killed fabric-admin with PID $fabric_admin_pid" +fi + +# Kill fabric-bridge-app if it is running +fabric_bridge_app_pid=$(pgrep -f "$FABRIC_BRIDGE_APP_PATH") +if [ ! -z "$fabric_bridge_app_pid" ]; then + kill -9 "$fabric_bridge_app_pid" + echo "Killed fabric-bridge-app with PID $fabric_bridge_app_pid" +fi + +# Remove /tmp/chip_* files and directories +sudo rm -rf /tmp/chip_* +echo "Removed /tmp/chip_* files and directories" diff --git a/examples/fabric-bridge-app/linux/Dockerfile b/examples/fabric-bridge-app/linux/Dockerfile deleted file mode 100644 index 5194431decc644..00000000000000 --- a/examples/fabric-bridge-app/linux/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -# -# 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. -# - -ARG VERSION=1 -FROM ghcr.io/project-chip/chip-cirque-device-base:${VERSION} -LABEL org.opencontainers.image.source https://github.com/project-chip/connectedhomeip - -COPY out/debug/chip-bridge-app /usr/bin/ -COPY entrypoint.sh / - -ENTRYPOINT ["/entrypoint.sh", "server"] diff --git a/examples/fabric-bridge-app/linux/RpcClient.cpp b/examples/fabric-bridge-app/linux/RpcClient.cpp index 815250f12bc328..c26d2b8f0aad31 100644 --- a/examples/fabric-bridge-app/linux/RpcClient.cpp +++ b/examples/fabric-bridge-app/linux/RpcClient.cpp @@ -19,9 +19,11 @@ #include "RpcClient.h" #include "RpcClientProcessor.h" +#include +#include +#include #include #include -#include #include "fabric_admin_service/fabric_admin_service.rpc.pb.h" #include "pw_assert/check.h" @@ -36,15 +38,44 @@ using namespace chip; namespace { // Constants +constexpr uint32_t kRpcTimeoutMs = 1000; constexpr uint32_t kDefaultChannelId = 1; // Fabric Admin Client rpc::pw_rpc::nanopb::FabricAdmin::Client fabricAdminClient(rpc::client::GetDefaultRpcClient(), kDefaultChannelId); pw::rpc::NanopbUnaryReceiver<::chip_rpc_OperationStatus> openCommissioningWindowCall; +std::mutex responseMutex; +std::condition_variable responseCv; +bool responseReceived = false; +CHIP_ERROR responseError = CHIP_NO_ERROR; + +template +CHIP_ERROR WaitForResponse(CallType & call) +{ + std::unique_lock lock(responseMutex); + responseReceived = false; + responseError = CHIP_NO_ERROR; + + if (responseCv.wait_for(lock, std::chrono::milliseconds(kRpcTimeoutMs), [] { return responseReceived; })) + { + return responseError; + } + else + { + ChipLogError(NotSpecified, "RPC Response timed out!"); + return CHIP_ERROR_TIMEOUT; + } +} + // Callback function to be called when the RPC response is received void OnOpenCommissioningWindowCompleted(const chip_rpc_OperationStatus & response, pw::Status status) { + std::lock_guard lock(responseMutex); + responseReceived = true; + responseError = status.ok() ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + responseCv.notify_one(); + if (status.ok()) { ChipLogProgress(NotSpecified, "OpenCommissioningWindow received operation status: %d", response.success); @@ -81,8 +112,9 @@ CHIP_ERROR OpenCommissioningWindow(NodeId nodeId) if (!openCommissioningWindowCall.active()) { + // The RPC call was not sent. This could occur due to, for example, an invalid channel ID. Handle if necessary. return CHIP_ERROR_INTERNAL; } - return CHIP_NO_ERROR; + return WaitForResponse(openCommissioningWindowCall); } diff --git a/examples/fabric-bridge-app/linux/include/RpcClient.h b/examples/fabric-bridge-app/linux/include/RpcClient.h index bd424e9d275910..34fa5c19de9349 100644 --- a/examples/fabric-bridge-app/linux/include/RpcClient.h +++ b/examples/fabric-bridge-app/linux/include/RpcClient.h @@ -37,7 +37,7 @@ CHIP_ERROR InitRpcClient(uint16_t rpcServerPort); * * @param nodeId The identifier of the node for which the commissioning window should be opened. * @return CHIP_ERROR An error code indicating the success or failure of the operation. - * - CHIP_NO_ERROR: The RPC command was successfully sent. + * - CHIP_NO_ERROR: The RPC command was successfully processed. * - CHIP_ERROR_BUSY: Another commissioning window is currently in progress. * - CHIP_ERROR_INTERNAL: An internal error occurred. */ diff --git a/examples/laundry-washer-app/nxp/zephyr/.gitignore b/examples/laundry-washer-app/nxp/zephyr/.gitignore new file mode 100644 index 00000000000000..84c048a73cc2e5 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/examples/laundry-washer-app/nxp/zephyr/CMakeLists.txt b/examples/laundry-washer-app/nxp/zephyr/CMakeLists.txt new file mode 100644 index 00000000000000..f7b32881ada959 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/CMakeLists.txt @@ -0,0 +1,116 @@ +# +# Copyright (c) 2023-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. +# +cmake_minimum_required(VERSION 3.13.1) + +get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connectedhomeip REALPATH) +get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) +get_filename_component(ALL_CLUSTERS_COMMON_DIR ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) +get_filename_component(LAUNDRY_WASHER_NXP_COMMON_DIR ${CHIP_ROOT}/examples/laundry-washer-app/nxp/common REALPATH) +get_filename_component(EXAMPLE_PLATFORM_NXP_COMMON_DIR ${CHIP_ROOT}/examples/platform/nxp/common REALPATH) +get_filename_component(EXAMPLE_PLATFORM_NXP_ZEPHYR_DIR ${CHIP_ROOT}/examples/platform/nxp/zephyr REALPATH) + +# Perform common operations like detecting extra overlays in the platform folder for the target board +# This must be called before find_package(Zephyr) +include(${CHIP_ROOT}/config/nxp/app/pre-zephyr.cmake) + +list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nxp/chip-module) +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) + +# -Wmaybe-uninitialized has too many false positives, including on std::optional +# and chip::Optional. Make it nonfatal. +# +# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635 +target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) +target_compile_options(app PRIVATE -Werror PRIVATE -Wno-error=format) + +project(chip-nxp-all-clusters-app-example) + +include(${CHIP_ROOT}/config/nxp/app/enable-gnu-std.cmake) +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) + +target_include_directories(app + PRIVATE + ${LAUNDRY_WASHER_NXP_COMMON_DIR}/main/include + ${LAUNDRY_WASHER_NXP_COMMON_DIR}/Zephyr/include + ${ALL_CLUSTERS_COMMON_DIR}/include + ${GEN_DIR}/app-common + ${GEN_DIR}/all-clusters-app + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_manager/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/icd/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_callbacks/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/factory_data/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/include +) + +target_sources(app + PRIVATE + main/main.cpp + ${LAUNDRY_WASHER_NXP_COMMON_DIR}/main/AppTask.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_manager/source/CHIPDeviceManager.cpp + ${LAUNDRY_WASHER_NXP_COMMON_DIR}/main/DeviceCallbacks.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_callbacks/source/CommonDeviceCallbacks.cpp + ${LAUNDRY_WASHER_NXP_COMMON_DIR}/main/ZclCallbacks.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/source/AppTaskBase.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/source/AppTaskZephyr.cpp + ${EXAMPLE_PLATFORM_NXP_ZEPHYR_DIR}/factory_data/source/AppFactoryDataExample.cpp +) + +target_compile_definitions(app PUBLIC + "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/zephyr/FactoryDataProviderImpl.h\"" +) + +if(CONFIG_CHIP_OTA_REQUESTOR) + target_sources(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/source/OTARequestorInitiatorCommon.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/source/OTARequestorInitiatorZephyr.cpp + ) + target_include_directories(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/include/ + ) +endif() + +chip_configure_data_model(app + INCLUDE_SERVER + ZAP_FILE ${ALL_CLUSTERS_COMMON_DIR}/../../laundry-washer-app/nxp/zap/laundry-washer-app.zap +) + +if(CONFIG_CHIP_LIB_SHELL) + target_compile_definitions(app PRIVATE ENABLE_CHIP_SHELL) + target_include_directories(app PRIVATE + ${CHIP_ROOT}/examples/shell/shell_common/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/include + ) + target_sources(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/source/AppCLIBase.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/source/AppCLIZephyr.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_misc.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_otcli.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_server.cpp + ) +endif() + +target_sources(app + PRIVATE + ${ALL_CLUSTERS_COMMON_DIR}/src/smco-stub.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/bridged-actions-stub.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-modes-manager.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-temperature-levels.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/laundry-washer-mode.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/laundry-washer-controls-delegate-impl.cpp + ${LAUNDRY_WASHER_NXP_COMMON_DIR}/main/operational-state-delegate-impl.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/icd/source/ICDUtil.cpp +) diff --git a/examples/laundry-washer-app/nxp/zephyr/Kconfig b/examples/laundry-washer-app/nxp/zephyr/Kconfig new file mode 100644 index 00000000000000..1d8b3f96581e51 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/Kconfig @@ -0,0 +1,20 @@ +# +# 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. +# +mainmenu "Matter NXP Laundry Washer Example Application" + +rsource "../../../../config/nxp/chip-module/Kconfig.features" +rsource "../../../../config/nxp/chip-module/Kconfig.defaults" +source "Kconfig.zephyr" diff --git a/examples/laundry-washer-app/nxp/zephyr/README.md b/examples/laundry-washer-app/nxp/zephyr/README.md new file mode 100644 index 00000000000000..406ee3b7796ede --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/README.md @@ -0,0 +1,4 @@ +# CHIP NXP Zephyr Laundry Washer Application + +All instructions describing how to use a Matter application on NXP Zephyr can be +found in [README.md](../../../all-clusters-app/nxp/zephyr/README.md) root readme diff --git a/examples/laundry-washer-app/nxp/zephyr/boards/rd_rw612_bga.overlay b/examples/laundry-washer-app/nxp/zephyr/boards/rd_rw612_bga.overlay new file mode 100644 index 00000000000000..86bb20739527cd --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/boards/rd_rw612_bga.overlay @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023-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. + */ + +/ { + chosen { + zephyr,console = &flexcomm0; + zephyr,shell-uart = &flexcomm3; + }; +}; + +&flexcomm0 { + compatible = "nxp,lpc-usart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm0_usart>; + pinctrl-names = "default"; +}; + +&flexcomm3 { + compatible = "nxp,lpc-usart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm3_usart>; + pinctrl-names = "default"; +}; diff --git a/examples/laundry-washer-app/nxp/zephyr/boards/rd_rw612_bga_fdata.conf b/examples/laundry-washer-app/nxp/zephyr/boards/rd_rw612_bga_fdata.conf new file mode 100644 index 00000000000000..73d139c3948d95 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/boards/rd_rw612_bga_fdata.conf @@ -0,0 +1,23 @@ +# +# Copyright (c) 2023-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. +# + +CONFIG_SETTINGS_NVS_SECTOR_COUNT=16 + +# 0xA226 +CONFIG_CHIP_DEVICE_PRODUCT_ID=41510 +CONFIG_CHIP_DEVICE_PRODUCT_URL="https://www.nxp.com/products/wireless-connectivity/wi-fi-plus-bluetooth-plus-802-15-4/wireless-mcu-with-integrated-tri-radio-1x1-wi-fi-6-plus-bluetooth-low-energy-5-3-802-15-4:RW612" +CONFIG_CHIP_DEVICE_PRODUCT_LABEL="RW612" +CONFIG_CHIP_DEVICE_PART_NUMBER="RW612" diff --git a/examples/laundry-washer-app/nxp/zephyr/main/include/CHIPProjectConfig.h b/examples/laundry-washer-app/nxp/zephyr/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..84c57df1ea140d --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/main/include/CHIPProjectConfig.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023-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. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR CONFIG_CHIP_DEVICE_DISCRIMINATOR + +// All clusters app has 3 group endpoints. This needs to defined here so that +// CHIP_CONFIG_MAX_GROUPS_PER_FABRIC is properly configured. +#define CHIP_CONFIG_MAX_GROUP_ENDPOINTS_PER_FABRIC 3 diff --git a/examples/laundry-washer-app/nxp/zephyr/main/main.cpp b/examples/laundry-washer-app/nxp/zephyr/main/main.cpp new file mode 100644 index 00000000000000..9be47dfe0a95d8 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/main/main.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023-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 "AppTask.h" + +#include + +LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); + +using namespace ::chip; + +int main() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + if (err == CHIP_NO_ERROR) + { + err = chip::NXP::App::GetAppTask().Start(); + } + + LOG_ERR("Exited with code %" CHIP_ERROR_FORMAT, err.Format()); + return err == CHIP_NO_ERROR ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/laundry-washer-app/nxp/zephyr/prj.conf b/examples/laundry-washer-app/nxp/zephyr/prj.conf new file mode 100644 index 00000000000000..ed59218a7da0e9 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/prj.conf @@ -0,0 +1,59 @@ +# +# Copyright (c) 2023-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. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_STD_CPP17=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y +# CHIP PID: 32769 == 0x8001 (all-clusters-app) +CONFIG_CHIP_DEVICE_PRODUCT_ID=32769 +CONFIG_CHIP_DEVICE_PRODUCT_NAME="Laundry Washer" +CONFIG_CHIP_DEVICE_DISCRIMINATOR=0x800 + +# Enable MbedTLS PSA - heavily experimental, not thread safe yet +# CONFIG_CHIP_CRYPTO_PSA=y + +# Bluetooth overrides +CONFIG_BT_DEVICE_NAME="LaundryWasher" + +# Additional configs for debbugging experience. +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y + +CONFIG_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_THREAD_INFO=y +# use this config if stepping during debug session is not consistent +# CONFIG_NO_OPTIMIZATIONS=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_ASSERT=y +# by default west will generate the full assembly output, which can take several minutes when binaries are large +CONFIG_OUTPUT_DISASSEMBLY=n +# embedded thread analyzer with thread statistics (stack usage, cpu usage...) +# CONFIG_THREAD_ANALYZER=y +# CONFIG_THREAD_ANALYZER_USE_PRINTK=y +# CONFIG_THREAD_ANALYZER_AUTO=y + +# enable Matter CLI +CONFIG_CHIP_LIB_SHELL=y +# enable NET commands if desired +#CONFIG_NET_SHELL=y +CONFIG_CHIP_STATISTICS=y diff --git a/examples/laundry-washer-app/nxp/zephyr/prj_fdata.conf b/examples/laundry-washer-app/nxp/zephyr/prj_fdata.conf new file mode 100644 index 00000000000000..986fc877aec5df --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/prj_fdata.conf @@ -0,0 +1,80 @@ +# +# Copyright (c) 2023-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. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_STD_CPP17=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable MbedTLS PSA - heavily experimental, not thread safe yet +# CONFIG_CHIP_CRYPTO_PSA=y + +# Bluetooth overrides +CONFIG_BT_DEVICE_NAME="LaundryWasher" + +# enable Matter CLI +CONFIG_CHIP_LIB_SHELL=y +CONFIG_CHIP_STATISTICS=y + +# Factory data configuration +CONFIG_CHIP_DEVICE_VENDOR_ID=4151 +CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xA00 +CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE=14014 +CONFIG_CHIP_DEVICE_PRODUCT_NAME="Laundry Washer" +CONFIG_CHIP_DEVICE_TYPE=115 +CONFIG_CHIP_DEVICE_MANUFACTURING_DATE="2023-01-01" +CONFIG_CHIP_DEVICE_SERIAL_NUMBER="12345678" +CONFIG_CHIP_DEVICE_PRODUCT_COLOR="Green" +CONFIG_CHIP_DEVICE_PRODUCT_FINISH="Matte" + +# Use factory data provider for device info +CONFIG_CHIP_FACTORY_DATA=y +# Generate factor data raw binary during the build process +# CONFIG_CHIP_FACTORY_DATA_BUILD=y +# Generate test certificates for factory data during the build process +# CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED=y +# Spake2p verifier will be generated during factory data generation +# CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER=y + +# Example of using pre-generated certificates +# CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_USER=y +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_CD_CERT="/Chip-Test-CD-1037-A226.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_CERT="/Chip-DAC-NXP-1037-A226-Cert.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_KEY="/Chip-DAC-NXP-1037-A226-Key.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_PAI_CERT="/Chip-PAI-NXP-1037-A226-Cert.der" + +# Additional configs for debbugging experience. +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y + +CONFIG_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_THREAD_INFO=y +# use this config if stepping during debug session is not consistent +# CONFIG_NO_OPTIMIZATIONS=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_ASSERT=y +# by default west will generate the full assembly output, which can take several minutes when binaries are large +CONFIG_OUTPUT_DISASSEMBLY=n +# embedded thread analyzer with thread statistics (stack usage, cpu usage...) +# CONFIG_THREAD_ANALYZER=y +# CONFIG_THREAD_ANALYZER_USE_PRINTK=y +# CONFIG_THREAD_ANALYZER_AUTO=y diff --git a/examples/laundry-washer-app/nxp/zephyr/prj_ota.conf b/examples/laundry-washer-app/nxp/zephyr/prj_ota.conf new file mode 100644 index 00000000000000..bdc65e94fabf70 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/prj_ota.conf @@ -0,0 +1,31 @@ +# +# 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. +# + +# Options needed for OTA are located on this file +# This file should contain only options specific for this sample +# or overrides the default ones. + +CONFIG_CHIP_OTA_REQUESTOR=y + +# To generate an OTA image based on the application +CONFIG_CHIP_OTA_IMAGE_BUILD=y + +# By default, MCUBOOT bootloader uses a signature key provided in their repository. +# Change the key to the appropriate one. +# Note: You need to use the same signature key used by MCUBOOT, i.e BOOT_SIGNATURE_KEY_FILE. +# Default CONFIG_BOOT_SIGNATURE_KEY_FILE is defined in config/nxp/app/bootloader.conf +CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="./bootloader/mcuboot/root-rsa-2048.pem" diff --git a/examples/laundry-washer-app/nxp/zephyr/third_party/connectedhomeip b/examples/laundry-washer-app/nxp/zephyr/third_party/connectedhomeip new file mode 120000 index 00000000000000..3efed95be5dbe9 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../ \ No newline at end of file diff --git a/examples/lighting-app/esp32/sdkconfig.defaults.esp32c2 b/examples/lighting-app/esp32/sdkconfig.defaults.esp32c2 index 5e5d596cacb673..2347f73ec8cc6c 100644 --- a/examples/lighting-app/esp32/sdkconfig.defaults.esp32c2 +++ b/examples/lighting-app/esp32/sdkconfig.defaults.esp32c2 @@ -18,5 +18,8 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=4 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=8 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=16 +# Event Queue Size +CONFIG_MAX_EVENT_QUEUE_SIZE=25 + # Enable HKDF in mbedtls CONFIG_MBEDTLS_HKDF_C=y diff --git a/examples/lock-app/lock-common/include/LockEndpoint.h b/examples/lock-app/lock-common/include/LockEndpoint.h index bd193d388db02b..aa67a69481f23d 100644 --- a/examples/lock-app/lock-common/include/LockEndpoint.h +++ b/examples/lock-app/lock-common/include/LockEndpoint.h @@ -18,7 +18,9 @@ #pragma once +#include #include +#include #include struct LockUserInfo @@ -38,10 +40,10 @@ struct WeekDaysScheduleInfo; struct YearDayScheduleInfo; struct HolidayScheduleInfo; -static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE = 20; -static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_TYPES = 6; +static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE = 65; +static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_TYPES = 9; -class LockEndpoint +class LockEndpoint : public chip::app::Clusters::DoorLock::Delegate { public: LockEndpoint(chip::EndpointId endpointId, uint16_t numberOfLockUsersSupported, uint16_t numberOfCredentialsSupported, @@ -60,6 +62,7 @@ class LockEndpoint } DoorLockServer::Instance().SetDoorState(endpointId, mDoorState); DoorLockServer::Instance().SetLockState(endpointId, mLockState); + chip::Crypto::DRBG_get_bytes(mAliroReaderGroupSubIdentifier, sizeof(mAliroReaderGroupSubIdentifier)); } inline chip::EndpointId GetEndpointId() const { return mEndpointId; } @@ -100,6 +103,22 @@ class LockEndpoint DlStatus SetSchedule(uint8_t holidayIndex, DlScheduleStatus status, uint32_t localStartTime, uint32_t localEndTime, OperatingModeEnum operatingMode); + // DoorLock::Delegate API. + CHIP_ERROR GetAliroReaderVerificationKey(chip::MutableByteSpan & verificationKey) override; + CHIP_ERROR GetAliroReaderGroupIdentifier(chip::MutableByteSpan & groupIdentifier) override; + CHIP_ERROR GetAliroReaderGroupSubIdentifier(chip::MutableByteSpan & groupSubIdentifier) override; + CHIP_ERROR GetAliroExpeditedTransactionSupportedProtocolVersionAtIndex(size_t index, + chip::MutableByteSpan & protocolVersion) override; + CHIP_ERROR GetAliroGroupResolvingKey(chip::MutableByteSpan & groupResolvingKey) override; + CHIP_ERROR GetAliroSupportedBLEUWBProtocolVersionAtIndex(size_t index, chip::MutableByteSpan & protocolVersion) override; + uint8_t GetAliroBLEAdvertisingVersion() override; + uint16_t GetNumberOfAliroCredentialIssuerKeysSupported() override; + uint16_t GetNumberOfAliroEndpointKeysSupported() override; + CHIP_ERROR SetAliroReaderConfig(const chip::ByteSpan & signingKey, const chip::ByteSpan & verificationKey, + const chip::ByteSpan & groupIdentifier, + const chip::Optional & groupResolvingKey) override; + CHIP_ERROR ClearAliroReaderConfig() override; + private: bool setLockState(const Nullable & fabricIdx, const Nullable & nodeId, DlLockState lockState, const Optional & pin, OperationErrorEnum & err, @@ -130,6 +149,14 @@ class LockEndpoint std::vector> mWeekDaySchedules; std::vector> mYearDaySchedules; std::vector mHolidaySchedules; + + // Actual Aliro state would presumably be stored somewhere else, and persistently; this + // example just stores it in memory for illustration purposes. + uint8_t mAliroReaderVerificationKey[chip::app::Clusters::DoorLock::kAliroReaderVerificationKeySize]; + uint8_t mAliroReaderGroupIdentifier[chip::app::Clusters::DoorLock::kAliroReaderGroupIdentifierSize]; + uint8_t mAliroReaderGroupSubIdentifier[chip::app::Clusters::DoorLock::kAliroReaderGroupSubIdentifierSize]; + uint8_t mAliroGroupResolvingKey[chip::app::Clusters::DoorLock::kAliroGroupResolvingKeySize]; + bool mAliroStateInitialized = false; }; struct LockCredentialInfo diff --git a/examples/lock-app/lock-common/include/LockManager.h b/examples/lock-app/lock-common/include/LockManager.h index 71dcf6f02dc072..fb4299a534622c 100644 --- a/examples/lock-app/lock-common/include/LockManager.h +++ b/examples/lock-app/lock-common/include/LockManager.h @@ -70,7 +70,12 @@ class LockManager private: LockEndpoint * getEndpoint(chip::EndpointId endpointId); - std::vector mEndpoints; + /** + * We store the LockEndpoint instances by pointer, not value, so + * LockEndpoint can have a stable location in memory, which lets it + * implement DoorLock::Delegate. + */ + std::vector> mEndpoints; static LockManager instance; }; diff --git a/examples/lock-app/lock-common/src/LockEndpoint.cpp b/examples/lock-app/lock-common/src/LockEndpoint.cpp index bda27f18ba2c8c..5481d01471cfd0 100644 --- a/examples/lock-app/lock-common/src/LockEndpoint.cpp +++ b/examples/lock-app/lock-common/src/LockEndpoint.cpp @@ -17,10 +17,15 @@ */ #include "LockEndpoint.h" #include +#include #include +#include #include #include +using chip::ByteSpan; +using chip::MutableByteSpan; +using chip::Optional; using chip::to_underlying; using chip::app::DataModel::MakeNullable; @@ -204,7 +209,8 @@ bool LockEndpoint::GetCredential(uint16_t credentialIndex, CredentialTypeEnum cr if (credentialIndex >= mLockCredentials.at(to_underlying(credentialType)).size() || (0 == credentialIndex && CredentialTypeEnum::kProgrammingPIN != credentialType)) { - ChipLogError(Zcl, "Cannot get the credential - index out of range [endpoint=%d,index=%d]", mEndpointId, credentialIndex); + ChipLogError(Zcl, "Cannot get the credential - index out of range [endpoint=%d,index=%d]: %d", mEndpointId, credentialIndex, + static_cast(mLockCredentials.at(to_underlying(credentialType)).size())); return false; } @@ -407,6 +413,149 @@ DlStatus LockEndpoint::SetSchedule(uint8_t holidayIndex, DlScheduleStatus status return DlStatus::kSuccess; } +CHIP_ERROR LockEndpoint::GetAliroReaderVerificationKey(MutableByteSpan & verificationKey) +{ + if (!mAliroStateInitialized) + { + verificationKey.reduce_size(0); + return CHIP_NO_ERROR; + } + + return chip::CopySpanToMutableSpan(ByteSpan(mAliroReaderVerificationKey), verificationKey); +} + +CHIP_ERROR LockEndpoint::GetAliroReaderGroupIdentifier(MutableByteSpan & groupIdentifier) +{ + if (!mAliroStateInitialized) + { + groupIdentifier.reduce_size(0); + return CHIP_NO_ERROR; + } + + return CopySpanToMutableSpan(ByteSpan(mAliroReaderGroupIdentifier), groupIdentifier); +} + +CHIP_ERROR LockEndpoint::GetAliroReaderGroupSubIdentifier(MutableByteSpan & groupSubIdentifier) +{ + return CopySpanToMutableSpan(ByteSpan(mAliroReaderGroupSubIdentifier), groupSubIdentifier); +} + +namespace { + +CHIP_ERROR CopyProtocolVersionIntoSpan(uint16_t protocolVersionValue, MutableByteSpan & protocolVersion) +{ + using namespace chip::app::Clusters::DoorLock; + + static_assert(sizeof(protocolVersionValue) == kAliroProtocolVersionSize); + + if (protocolVersion.size() < kAliroProtocolVersionSize) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + + // Per Aliro spec, protocol version encoding is big-endian + chip::Encoding::BigEndian::Put16(protocolVersion.data(), protocolVersionValue); + protocolVersion.reduce_size(kAliroProtocolVersionSize); + return CHIP_NO_ERROR; +} + +} // anonymous namespace + +CHIP_ERROR LockEndpoint::GetAliroExpeditedTransactionSupportedProtocolVersionAtIndex(size_t index, + MutableByteSpan & protocolVersion) +{ + // Only claim support for the one known protocol version for now: 0x0100. + constexpr uint16_t knownProtocolVersion = 0x0100; + + if (index > 0) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } + + return CopyProtocolVersionIntoSpan(knownProtocolVersion, protocolVersion); +} + +CHIP_ERROR LockEndpoint::GetAliroGroupResolvingKey(MutableByteSpan & groupResolvingKey) +{ + if (!mAliroStateInitialized) + { + groupResolvingKey.reduce_size(0); + return CHIP_NO_ERROR; + } + + return CopySpanToMutableSpan(ByteSpan(mAliroGroupResolvingKey), groupResolvingKey); +} + +CHIP_ERROR LockEndpoint::GetAliroSupportedBLEUWBProtocolVersionAtIndex(size_t index, MutableByteSpan & protocolVersion) +{ + // Only claim support for the one known protocol version for now: 0x0100. + constexpr uint16_t knownProtocolVersion = 0x0100; + + if (index > 0) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } + + return CopyProtocolVersionIntoSpan(knownProtocolVersion, protocolVersion); +} + +uint8_t LockEndpoint::GetAliroBLEAdvertisingVersion() +{ + // For now the only define value of the BLE advertising version for Aliro is 0. + return 0; +} + +uint16_t LockEndpoint::GetNumberOfAliroCredentialIssuerKeysSupported() +{ + using namespace chip::app::Clusters::DoorLock; + + // Our vector has an extra entry at index 0 that is not a valid entry, so + // the actual number of credentials supported is one length than the length. + return static_cast(mLockCredentials.at(to_underlying(CredentialTypeEnum::kAliroCredentialIssuerKey)).size() - 1); +} + +uint16_t LockEndpoint::GetNumberOfAliroEndpointKeysSupported() +{ + using namespace chip::app::Clusters::DoorLock; + + // Our vector has an extra entry at index 0 that is not a valid entry, so + // the actual number of credentials supported is one length than the length. + // + // Also, our arrays are the same size, so we just return the size of one of + // the arrays: that is the cap on the total number of endpoint keys + // supported, which can be of either type. + return static_cast(mLockCredentials.at(to_underlying(CredentialTypeEnum::kAliroEvictableEndpointKey)).size() - 1); +} + +CHIP_ERROR LockEndpoint::SetAliroReaderConfig(const ByteSpan & signingKey, const ByteSpan & verificationKey, + const ByteSpan & groupIdentifier, const Optional & groupResolvingKey) +{ + // We ignore the signing key, since we never do anything with it. + + VerifyOrReturnError(verificationKey.size() == sizeof(mAliroReaderVerificationKey), CHIP_ERROR_INVALID_ARGUMENT); + memcpy(mAliroReaderVerificationKey, verificationKey.data(), sizeof(mAliroReaderVerificationKey)); + + VerifyOrReturnError(groupIdentifier.size() == sizeof(mAliroReaderGroupIdentifier), CHIP_ERROR_INVALID_ARGUMENT); + memcpy(mAliroReaderGroupIdentifier, groupIdentifier.data(), sizeof(mAliroReaderGroupIdentifier)); + + if (groupResolvingKey.HasValue()) + { + VerifyOrReturnError(groupResolvingKey.Value().size() == sizeof(mAliroGroupResolvingKey), CHIP_ERROR_INVALID_ARGUMENT); + memcpy(mAliroGroupResolvingKey, groupResolvingKey.Value().data(), sizeof(mAliroGroupResolvingKey)); + } + + mAliroStateInitialized = true; + return CHIP_NO_ERROR; +} + +CHIP_ERROR LockEndpoint::ClearAliroReaderConfig() +{ + // A real implementation would clear out key data from the other parts of + // the application that might use it. + mAliroStateInitialized = false; + return CHIP_NO_ERROR; +} + bool LockEndpoint::setLockState(const Nullable & fabricIdx, const Nullable & nodeId, DlLockState lockState, const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource) diff --git a/examples/lock-app/lock-common/src/LockManager.cpp b/examples/lock-app/lock-common/src/LockManager.cpp index 8fd1ef5441b139..8af66051883aa4 100644 --- a/examples/lock-app/lock-common/src/LockManager.cpp +++ b/examples/lock-app/lock-common/src/LockManager.cpp @@ -20,6 +20,7 @@ #include #include +#include using chip::to_underlying; @@ -98,8 +99,9 @@ bool LockManager::InitEndpoint(chip::EndpointId endpointId) numberOfHolidaySchedules = 10; } - mEndpoints.emplace_back(endpointId, numberOfSupportedUsers, numberOfSupportedCredentials, numberOfWeekDaySchedulesPerUser, - numberOfYearDaySchedulesPerUser, numberOfCredentialsSupportedPerUser, numberOfHolidaySchedules); + mEndpoints.emplace_back(std::make_unique(endpointId, numberOfSupportedUsers, numberOfSupportedCredentials, + numberOfWeekDaySchedulesPerUser, numberOfYearDaySchedulesPerUser, + numberOfCredentialsSupportedPerUser, numberOfHolidaySchedules)); ChipLogProgress(Zcl, "Initialized new lock door endpoint " @@ -107,6 +109,7 @@ bool LockManager::InitEndpoint(chip::EndpointId endpointId) "numberOfCredentialsSupportedPerUser=%d,holidaySchedules=%d]", endpointId, numberOfSupportedUsers, numberOfSupportedCredentials, numberOfWeekDaySchedulesPerUser, numberOfYearDaySchedulesPerUser, numberOfCredentialsSupportedPerUser, numberOfHolidaySchedules); + DoorLockServer::Instance().SetDelegate(endpointId, mEndpoints.back().get()); return true; } @@ -303,11 +306,11 @@ DlStatus LockManager::SetSchedule(chip::EndpointId endpointId, uint8_t holidayIn LockEndpoint * LockManager::getEndpoint(chip::EndpointId endpointId) { - for (auto & mEndpoint : mEndpoints) + for (auto & endpoint : mEndpoints) { - if (mEndpoint.GetEndpointId() == endpointId) + if (endpoint->GetEndpointId() == endpointId) { - return &mEndpoint; + return endpoint.get(); } } return nullptr; diff --git a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp index 5253b3b2ec5062..59bf52bbc0f30f 100644 --- a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp +++ b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp @@ -19,9 +19,10 @@ #include #include -#include "silabs_utils.h" #include "sl_status.h" #include +#include +#include #include "FreeRTOS.h" #include "event_groups.h" @@ -132,14 +133,14 @@ static void CancelDHCPTimer() // Check if timer started if (!osTimerIsRunning(sDHCPTimer)) { - SILABS_LOG("CancelDHCPTimer: timer not running"); + ChipLogDetail(DeviceLayer, "CancelDHCPTimer: timer not running"); return; } status = osTimerStop(sDHCPTimer); if (status != osOK) { - SILABS_LOG("CancelDHCPTimer: failed to stop timer with status: %d", status); + ChipLogError(DeviceLayer, "CancelDHCPTimer: failed to stop timer: %d", status); } } @@ -153,7 +154,7 @@ static void StartDHCPTimer(uint32_t timeout) status = osTimerStart(sDHCPTimer, pdMS_TO_TICKS(timeout)); if (status != osOK) { - SILABS_LOG("StartDHCPTimer: failed to start timer with status: %d", status); + ChipLogError(DeviceLayer, "StartDHCPTimer: failed to start timer: %d", status); } } @@ -171,7 +172,7 @@ int32_t wfx_rsi_get_ap_info(wfx_wifi_scan_result_t * ap) int32_t rssi = 0; ap->security = wfx_rsi.sec.security; ap->chan = wfx_rsi.ap_chan; - memcpy(&ap->bssid[0], &wfx_rsi.ap_mac.octet[0], BSSID_MAX_STR_LEN); + memcpy(&ap->bssid[0], &wfx_rsi.ap_mac.octet[0], BSSID_LEN); sl_wifi_get_signal_strength(SL_WIFI_CLIENT_INTERFACE, &rssi); ap->rssi = rssi; return status; @@ -246,7 +247,7 @@ sl_status_t join_callback_handler(sl_wifi_event_t event, char * result, uint32_t if (SL_WIFI_CHECK_IF_EVENT_FAILED(event)) { callback_status = *(sl_status_t *) result; - SILABS_LOG("join_callback_handler: failed: 0x%X", callback_status); + ChipLogError(DeviceLayer, "join_callback_handler: failed: 0x%lx", static_cast(callback_status)); wfx_rsi.dev_state &= ~(WFX_RSI_ST_STA_CONNECTED); wfx_retry_interval_handler(is_wifi_disconnection_event, wfx_rsi.join_retries++); if (is_wifi_disconnection_event || wfx_rsi.join_retries <= WFX_RSI_CONFIG_MAX_JOIN) @@ -259,8 +260,8 @@ sl_status_t join_callback_handler(sl_wifi_event_t event, char * result, uint32_t /* * Join was complete - Do the DHCP */ - memset(&temp_reset, 0, sizeof(wfx_wifi_scan_ext_t)); - SILABS_LOG("join_callback_handler: success"); + ChipLogDetail(DeviceLayer, "join_callback_handler: success"); + memset(&temp_reset, 0, sizeof(temp_reset)); WfxEvent.eventType = WFX_EVT_STA_CONN; WfxPostEvent(&WfxEvent); @@ -329,14 +330,14 @@ int32_t wfx_rsi_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_ status = rsi_bt_power_save_profile(sl_si91x_ble_state, 0); if (status != RSI_SUCCESS) { - SILABS_LOG("BT Powersave Config Failed, Error Code : 0x%lX", status); + ChipLogError(DeviceLayer, "rsi_bt_power_save_profile failed: 0x%lx", static_cast(status)); return status; } sl_wifi_performance_profile_t wifi_profile = { .profile = sl_si91x_wifi_state }; status = sl_wifi_set_performance_profile(&wifi_profile); if (status != RSI_SUCCESS) { - SILABS_LOG("Powersave Config Failed, Error Code : 0x%lX", status); + ChipLogError(DeviceLayer, "sl_wifi_set_performance_profile failed: 0x%lx", static_cast(status)); return status; } if (sl_si91x_wifi_state == HIGH_PERFORMANCE) @@ -361,34 +362,23 @@ int32_t wfx_rsi_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_ *****************************************************************************************/ int32_t wfx_wifi_rsi_init(void) { - SILABS_LOG("wfx_wifi_rsi_init started"); + ChipLogDetail(DeviceLayer, "wfx_wifi_rsi_init started"); sl_status_t status; status = sl_wifi_init(&config, NULL, sl_wifi_default_event_handler); - if (status != SL_STATUS_OK) - { - return status; - } + VerifyOrReturnError(status == SL_STATUS_OK, status); // Create Sempaphore for scan sScanSemaphore = osSemaphoreNew(1, 0, NULL); - if (sScanSemaphore == NULL) - { - return SL_STATUS_ALLOCATION_FAILED; - } + VerifyOrReturnError(sScanSemaphore != NULL, SL_STATUS_ALLOCATION_FAILED); + // Create the message queue sWifiEventQueue = osMessageQueueNew(WFX_QUEUE_SIZE, sizeof(WfxEvent_t), NULL); - if (sWifiEventQueue == NULL) - { - return SL_STATUS_ALLOCATION_FAILED; - } + VerifyOrReturnError(sWifiEventQueue != NULL, SL_STATUS_ALLOCATION_FAILED); // Create timer for DHCP polling // TODO: Use LWIP timer instead of creating a new one here sDHCPTimer = osTimerNew(DHCPTimerEventHandler, osTimerPeriodic, NULL, NULL); - if (sDHCPTimer == NULL) - { - return SL_STATUS_ALLOCATION_FAILED; - } + VerifyOrReturnError(sDHCPTimer != NULL, SL_STATUS_ALLOCATION_FAILED); return status; } @@ -403,9 +393,9 @@ int32_t wfx_wifi_rsi_init(void) *****************************************************************************************/ static void sl_print_firmware_version(sl_wifi_firmware_version_t * firmware_version) { - SILABS_LOG("Firmware version is: %x%x.%d.%d.%d.%d.%d.%d", firmware_version->chip_id, firmware_version->rom_id, - firmware_version->major, firmware_version->minor, firmware_version->security_version, firmware_version->patch_num, - firmware_version->customer_id, firmware_version->build_num); + ChipLogDetail(DeviceLayer, "Firmware version is: %x%x.%d.%d.%d.%d.%d.%d", firmware_version->chip_id, firmware_version->rom_id, + firmware_version->major, firmware_version->minor, firmware_version->security_version, firmware_version->patch_num, + firmware_version->customer_id, firmware_version->build_num); } /************************************************************************************* @@ -424,7 +414,7 @@ static sl_status_t wfx_rsi_init(void) status = wfx_wifi_rsi_init(); if (status != SL_STATUS_OK) { - SILABS_LOG("wfx_rsi_init failed %x", status); + ChipLogError(DeviceLayer, "wfx_rsi_init failed: 0x%lx", static_cast(status)); return status; } #else // For SoC @@ -433,7 +423,7 @@ static sl_status_t wfx_rsi_init(void) status = sl_si91x_m4_ta_secure_handshake(SL_SI91X_ENABLE_XTAL, 1, &xtal_enable, 0, NULL); if (status != SL_STATUS_OK) { - SILABS_LOG("Failed to bring m4_ta_secure_handshake: 0x%lx\r\n", status); + ChipLogError(DeviceLayer, "sl_si91x_m4_ta_secure_handshake failed: 0x%lx", static_cast(status)); return status; } #endif /* CHIP_CONFIG_ENABLE_ICD_SERVER */ @@ -443,8 +433,7 @@ static sl_status_t wfx_rsi_init(void) status = sl_wifi_get_firmware_version(&version); if (status != SL_STATUS_OK) { - SILABS_LOG("Get fw version failed:"); - sl_print_firmware_version(&version); + ChipLogError(DeviceLayer, "sl_wifi_get_firmware_version failed: 0x%lx", static_cast(status)); return status; } sl_print_firmware_version(&version); @@ -452,7 +441,7 @@ static sl_status_t wfx_rsi_init(void) status = sl_wifi_get_mac_address(SL_WIFI_CLIENT_INTERFACE, (sl_mac_address_t *) &wfx_rsi.sta_mac.octet[0]); if (status != SL_STATUS_OK) { - SILABS_LOG("sl_wifi_get_mac_address failed: %x", status); + ChipLogDetail(DeviceLayer, "sl_wifi_get_mac_address failed: 0x%lx", static_cast(status)); return status; } @@ -463,7 +452,7 @@ static sl_status_t wfx_rsi_init(void) status = sl_si91x_trng_entropy(); if (status != SL_STATUS_OK) { - SILABS_LOG("TRNG Entropy Failed"); + ChipLogError(DeviceLayer, "sl_si91x_trng_entropy failed: 0x%lx", static_cast(status)); return status; } @@ -471,7 +460,7 @@ static sl_status_t wfx_rsi_init(void) status = sl_si91x_trng_program_key((uint32_t *) trngKey, TRNG_KEY_SIZE); if (status != SL_STATUS_OK) { - SILABS_LOG("TRNG Key Programming Failed"); + ChipLogError(DeviceLayer, "sl_si91x_trng_program_key failed: 0x%lx", static_cast(status)); return status; } #endif // SL_MBEDTLS_USE_TINYCRYPT @@ -492,7 +481,7 @@ static sl_status_t wfx_rsi_init(void) *****************************************************************************************/ void wfx_show_err(char * msg) { - SILABS_LOG("wfx_show_err: message: %d", msg); + ChipLogError(DeviceLayer, "wfx_show_err: message: %s", msg); } sl_status_t scan_callback_handler(sl_wifi_event_t event, sl_wifi_scan_result_t * scan_result, uint32_t result_length, void * arg) @@ -500,12 +489,12 @@ sl_status_t scan_callback_handler(sl_wifi_event_t event, sl_wifi_scan_result_t * if (SL_WIFI_CHECK_IF_EVENT_FAILED(event)) { callback_status = *(sl_status_t *) scan_result; - SILABS_LOG("scan_callback_handler: failed: 0x%X", callback_status); + ChipLogError(DeviceLayer, "scan_callback_handler: failed: 0x%lx", static_cast(callback_status)); scan_results_complete = true; #if WIFI_ENABLE_SECURITY_WPA3_TRANSITION wfx_rsi.sec.security = WFX_SEC_WPA3; #else - wfx_rsi.sec.security = WFX_SEC_WPA2; + wfx_rsi.sec.security = WFX_SEC_WPA2; #endif /* WIFI_ENABLE_SECURITY_WPA3_TRANSITION */ osSemaphoreRelease(sScanSemaphore); @@ -513,7 +502,7 @@ sl_status_t scan_callback_handler(sl_wifi_event_t event, sl_wifi_scan_result_t * } wfx_rsi.sec.security = WFX_SEC_UNSPECIFIED; wfx_rsi.ap_chan = scan_result->scan_info[0].rf_channel; - memcpy(&wfx_rsi.ap_mac.octet, scan_result->scan_info[0].bssid, BSSID_MAX_STR_LEN); + memcpy(&wfx_rsi.ap_mac.octet, scan_result->scan_info[0].bssid, BSSID_LEN); switch (scan_result->scan_info[0].security_mode) { case SL_WIFI_OPEN: @@ -536,7 +525,7 @@ sl_status_t scan_callback_handler(sl_wifi_event_t event, sl_wifi_scan_result_t * case SL_WIFI_WPA3: wfx_rsi.sec.security = WFX_SEC_WPA3; #else - wfx_rsi.sec.security = WFX_SEC_WPA2; + wfx_rsi.sec.security = WFX_SEC_WPA2; #endif /* WIFI_ENABLE_SECURITY_WPA3_TRANSITION */ break; default: @@ -549,44 +538,48 @@ sl_status_t scan_callback_handler(sl_wifi_event_t event, sl_wifi_scan_result_t * osSemaphoreRelease(sScanSemaphore); return SL_STATUS_OK; } + sl_status_t show_scan_results(sl_wifi_scan_result_t * scan_result) { SL_WIFI_ARGS_CHECK_NULL_POINTER(scan_result); - int x; - wfx_wifi_scan_result_t ap; - for (x = 0; x < (int) scan_result->scan_count; x++) + VerifyOrReturnError(wfx_rsi.scan_cb != NULL, SL_STATUS_INVALID_HANDLE); + + wfx_wifi_scan_result_t cur_scan_result; + for (int idx = 0; idx < (int) scan_result->scan_count; idx++) { - strcpy(&ap.ssid[0], (char *) &scan_result->scan_info[x].ssid); - if (wfx_rsi.scan_ssid) + memset(&cur_scan_result, 0, sizeof(cur_scan_result)); + strncpy(cur_scan_result.ssid, (char *) &scan_result->scan_info[idx].ssid, WFX_MAX_SSID_LENGTH); + + // if user has provided ssid, then check if the current scan result ssid matches the user provided ssid + if (wfx_rsi.scan_ssid != NULL && strcmp(wfx_rsi.scan_ssid, cur_scan_result.ssid) != CMP_SUCCESS) { - SILABS_LOG("SCAN SSID: %s , ap scan: %s", wfx_rsi.scan_ssid, ap.ssid); - if (strcmp(wfx_rsi.scan_ssid, ap.ssid) == CMP_SUCCESS) - { - ap.security = static_cast(scan_result->scan_info[x].security_mode); - ap.rssi = (-1) * scan_result->scan_info[x].rssi_val; - memcpy(&ap.bssid[0], &scan_result->scan_info[x].bssid[0], BSSID_MAX_STR_LEN); - (*wfx_rsi.scan_cb)(&ap); - break; - } + continue; } - else + cur_scan_result.security = static_cast(scan_result->scan_info[idx].security_mode); + cur_scan_result.rssi = (-1) * scan_result->scan_info[idx].rssi_val; + memcpy(cur_scan_result.bssid, scan_result->scan_info[idx].bssid, BSSID_LEN); + wfx_rsi.scan_cb(&cur_scan_result); + + // if user has not provided the ssid, then call the callback for each scan result + if (wfx_rsi.scan_ssid == NULL) { - ap.security = static_cast(scan_result->scan_info[x].security_mode); - ap.rssi = (-1) * scan_result->scan_info[x].rssi_val; - memcpy(&ap.bssid[0], &scan_result->scan_info[x].bssid[0], BSSID_MAX_STR_LEN); - (*wfx_rsi.scan_cb)(&ap); + continue; } + break; } + + // cleanup and return wfx_rsi.dev_state &= ~WFX_RSI_ST_SCANSTARTED; - (*wfx_rsi.scan_cb)((wfx_wifi_scan_result_t *) 0); - wfx_rsi.scan_cb = (void (*)(wfx_wifi_scan_result_t *)) 0; + wfx_rsi.scan_cb((wfx_wifi_scan_result_t *) 0); + wfx_rsi.scan_cb = NULL; if (wfx_rsi.scan_ssid) { vPortFree(wfx_rsi.scan_ssid); - wfx_rsi.scan_ssid = (char *) 0; + wfx_rsi.scan_ssid = NULL; } return SL_STATUS_OK; } + sl_status_t bg_scan_callback_handler(sl_wifi_event_t event, sl_wifi_scan_result_t * result, uint32_t result_length, void * arg) { callback_status = show_scan_results(result); @@ -605,16 +598,18 @@ sl_status_t bg_scan_callback_handler(sl_wifi_event_t event, sl_wifi_scan_result_ static void wfx_rsi_save_ap_info() // translation { sl_status_t status = SL_STATUS_OK; -#ifndef EXP_BOARD // TODO: this changes will be reverted back after the SDK team fix the scan API +#ifndef EXP_BOARD + // TODO: this changes will be reverted back after the Silabs WiFi SDK team fix the scan API sl_wifi_scan_configuration_t wifi_scan_configuration = default_wifi_scan_configuration; #endif sl_wifi_ssid_t ssid_arg; - ssid_arg.length = strlen(wfx_rsi.sec.ssid); - memcpy(ssid_arg.value, (int8_t *) &wfx_rsi.sec.ssid[0], ssid_arg.length); + memset(&ssid_arg, 0, sizeof(ssid_arg)); + ssid_arg.length = strnlen(wfx_rsi.sec.ssid, WFX_MAX_SSID_LENGTH); + strncpy((char *) &ssid_arg.value[0], wfx_rsi.sec.ssid, WFX_MAX_SSID_LENGTH); sl_wifi_set_scan_callback(scan_callback_handler, NULL); scan_results_complete = false; #ifndef EXP_BOARD - // TODO: this changes will be reverted back after the SDK team fix the scan API + // TODO: this changes will be reverted back after the Silabs WiFi SDK team fix the scan API status = sl_wifi_start_scan(SL_WIFI_CLIENT_2_4GHZ_INTERFACE, &ssid_arg, &wifi_scan_configuration); #endif if (SL_STATUS_IN_PROGRESS == status) @@ -632,115 +627,81 @@ static void wfx_rsi_save_ap_info() // translation **********************************************************************************************/ static sl_status_t wfx_rsi_do_join(void) { + ReturnErrorCodeIf((wfx_rsi.dev_state & (WFX_RSI_ST_STA_CONNECTING | WFX_RSI_ST_STA_CONNECTED)), SL_STATUS_IN_PROGRESS); sl_status_t status = SL_STATUS_OK; - sl_wifi_security_t connect_security_mode; + sl_wifi_client_configuration_t ap; + memset(&ap, 0, sizeof(ap)); WfxEvent_t event; switch (wfx_rsi.sec.security) { case WFX_SEC_WEP: - connect_security_mode = SL_WIFI_WEP; + ap.security = SL_WIFI_WEP; break; case WFX_SEC_WPA: - connect_security_mode = SL_WIFI_WPA_WPA2_MIXED; + ap.security = SL_WIFI_WPA_WPA2_MIXED; break; case WFX_SEC_WPA2: #if WIFI_ENABLE_SECURITY_WPA3_TRANSITION - connect_security_mode = SL_WIFI_WPA3_TRANSITION; + ap.security = SL_WIFI_WPA3_TRANSITION; break; case WFX_SEC_WPA3: - connect_security_mode = SL_WIFI_WPA3_TRANSITION; + ap.security = SL_WIFI_WPA3_TRANSITION; #else - connect_security_mode = SL_WIFI_WPA_WPA2_MIXED; + ap.security = SL_WIFI_WPA_WPA2_MIXED; #endif // WIFI_ENABLE_SECURITY_WPA3_TRANSITION break; case WFX_SEC_NONE: - connect_security_mode = SL_WIFI_OPEN; + ap.security = SL_WIFI_OPEN; break; default: - SILABS_LOG("error: unknown security type."); + ChipLogError(DeviceLayer, "wfx_rsi_do_join: unknown security type."); return status; } - - if (wfx_rsi.dev_state & (WFX_RSI_ST_STA_CONNECTING | WFX_RSI_ST_STA_CONNECTED)) - { - SILABS_LOG("%s: not joining - already in progress", __func__); - } - else - { - SILABS_LOG("%s: WLAN: connecting to %s, sec=%d", __func__, &wfx_rsi.sec.ssid[0], wfx_rsi.sec.security); - - /* - * Join the network - */ - /* TODO - make the WFX_SECURITY_xxx - same as RSI_xxx - * Right now it's done by hand - we need something better - */ - wfx_rsi.dev_state |= WFX_RSI_ST_STA_CONNECTING; - - sl_wifi_set_join_callback(join_callback_handler, NULL); + /* + * Join the network + */ + wfx_rsi.dev_state |= WFX_RSI_ST_STA_CONNECTING; + status = sl_wifi_set_join_callback(join_callback_handler, NULL); + VerifyOrReturnError(status == SL_STATUS_OK, status); #if CHIP_CONFIG_ENABLE_ICD_SERVER - // Setting the listen interval to 0 which will set it to DTIM interval - sl_wifi_listen_interval_t sleep_interval = { .listen_interval = 0 }; - status = sl_wifi_set_listen_interval(SL_WIFI_CLIENT_INTERFACE, sleep_interval); - - sl_wifi_advanced_client_configuration_t client_config = { .max_retry_attempts = 5 }; - sl_wifi_set_advanced_client_configuration(SL_WIFI_CLIENT_INTERFACE, &client_config); + // Setting the listen interval to 0 which will set it to DTIM interval + sl_wifi_listen_interval_t sleep_interval = { .listen_interval = 0 }; + status = sl_wifi_set_listen_interval(SL_WIFI_CLIENT_INTERFACE, sleep_interval); + VerifyOrReturnError(status == SL_STATUS_OK, status); + + sl_wifi_advanced_client_configuration_t client_config = { .max_retry_attempts = 5 }; + status = sl_wifi_set_advanced_client_configuration(SL_WIFI_CLIENT_INTERFACE, &client_config); + VerifyOrReturnError(status == SL_STATUS_OK, status); #endif // CHIP_CONFIG_ENABLE_ICD_SERVER - /* Try to connect Wifi with given Credentials - * untill there is a success or maximum number of tries allowed - */ - - /* Call rsi connect call with given ssid and password - * And check there is a success - */ - sl_wifi_credential_t cred; - memset(&cred, 0, sizeof(sl_wifi_credential_t)); - cred.type = SL_WIFI_PSK_CREDENTIAL; - memcpy(cred.psk.value, &wfx_rsi.sec.passkey[0], strlen(wfx_rsi.sec.passkey)); - sl_net_credential_id_t id = SL_NET_DEFAULT_WIFI_CLIENT_CREDENTIAL_ID; - status = sl_net_set_credential(id, SL_NET_WIFI_PSK, &wfx_rsi.sec.passkey[0], strlen(wfx_rsi.sec.passkey)); - if (SL_STATUS_OK != status) - { - SILABS_LOG("wfx_rsi_do_join: RSI callback register join failed with status: %02x", status); - return status; - } - - sl_wifi_client_configuration_t ap = { 0 }; - uint32_t timeout_ms = 0; - - ap.ssid.length = strlen(wfx_rsi.sec.ssid); - memcpy(ap.ssid.value, (int8_t *) &wfx_rsi.sec.ssid[0], ap.ssid.length); - ap.security = connect_security_mode; - ap.encryption = SL_WIFI_NO_ENCRYPTION; - ap.credential_id = id; - if ((status = sl_wifi_connect(SL_WIFI_CLIENT_INTERFACE, &ap, timeout_ms)) == SL_STATUS_IN_PROGRESS) - { - callback_status = SL_STATUS_IN_PROGRESS; - while (callback_status == SL_STATUS_IN_PROGRESS) - { - osThreadYield(); - } - status = callback_status; - } - else - { - if (is_wifi_disconnection_event || wfx_rsi.join_retries <= WFX_RSI_CONFIG_MAX_JOIN) - { - SILABS_LOG("wfx_rsi_do_join: Wifi connect failed with status: %x", status); - SILABS_LOG("wfx_rsi_do_join: starting JOIN to %s after %d tries\n", (char *) &wfx_rsi.sec.ssid[0], - wfx_rsi.join_retries); - wfx_rsi.join_retries += 1; - wfx_rsi.dev_state &= ~(WFX_RSI_ST_STA_CONNECTING | WFX_RSI_ST_STA_CONNECTED); - wfx_retry_interval_handler(is_wifi_disconnection_event, wfx_rsi.join_retries); - if (is_wifi_disconnection_event || wfx_rsi.join_retries <= MAX_JOIN_RETRIES_COUNT) - { - event.eventType = WFX_EVT_STA_START_JOIN; - WfxPostEvent(&event); - } - } - } - } + size_t psk_length = strlen(wfx_rsi.sec.passkey); + VerifyOrReturnError(psk_length <= SL_WIFI_MAX_PSK_LENGTH, SL_STATUS_SI91X_INVALID_PSK_LENGTH); + sl_net_credential_id_t id = SL_NET_DEFAULT_WIFI_CLIENT_CREDENTIAL_ID; + status = sl_net_set_credential(id, SL_NET_WIFI_PSK, &wfx_rsi.sec.passkey[0], psk_length); + VerifyOrReturnError(status == SL_STATUS_OK, status); + + uint32_t timeout_ms = 0; + ap.ssid.length = strnlen(wfx_rsi.sec.ssid, WFX_MAX_SSID_LENGTH); + ap.encryption = SL_WIFI_NO_ENCRYPTION; + ap.credential_id = id; + memset(&ap.ssid.value, 0, (sizeof(ap.ssid.value) / sizeof(ap.ssid.value[0]))); + strncpy((char *) &ap.ssid.value[0], wfx_rsi.sec.ssid, WFX_MAX_SSID_LENGTH); + ChipLogDetail(DeviceLayer, "wfx_rsi_do_join: SSID: %s, SECURITY: %d(%d)", ap.ssid.value, ap.security, wfx_rsi.sec.security); + status = sl_wifi_connect(SL_WIFI_CLIENT_INTERFACE, &ap, timeout_ms); + // sl_wifi_connect returns SL_STATUS_IN_PROGRESS if join is in progress + // after the initial scan is done, the scan does not check for SSID + ReturnErrorCodeIf((status == SL_STATUS_OK || status == SL_STATUS_IN_PROGRESS), status); + + // failure only happens when the firmware returns an error + ChipLogError(DeviceLayer, "wfx_rsi_do_join: sl_wifi_connect failed: 0x%lx", static_cast(status)); + VerifyOrReturnError((is_wifi_disconnection_event || wfx_rsi.join_retries <= MAX_JOIN_RETRIES_COUNT), status); + + wfx_rsi.dev_state &= ~(WFX_RSI_ST_STA_CONNECTING | WFX_RSI_ST_STA_CONNECTED); + ChipLogProgress(DeviceLayer, "wfx_rsi_do_join: retry attempt %d", wfx_rsi.join_retries); + wfx_retry_interval_handler(is_wifi_disconnection_event, wfx_rsi.join_retries); + wfx_rsi.join_retries++; + event.eventType = WFX_EVT_STA_START_JOIN; + WfxPostEvent(&event); return status; } @@ -765,7 +726,7 @@ void HandleDHCPPolling() if (sta_netif == NULL) { // TODO: Notify the application that the interface is not set up or Chipdie here because we are in an unkonwn state - SILABS_LOG("HandleDHCPPolling: failed to get STA netif"); + ChipLogError(DeviceLayer, "HandleDHCPPolling: failed to get STA netif"); return; } #if (CHIP_DEVICE_CONFIG_ENABLE_IPV4) @@ -787,6 +748,9 @@ void HandleDHCPPolling() */ if ((ip6_addr_ispreferred(netif_ip6_addr_state(sta_netif, 0))) && !hasNotifiedIPV6) { + char addrStr[chip::Inet::IPAddress::kMaxStringLength] = { 0 }; + VerifyOrReturn(ip6addr_ntoa_r(netif_ip6_addr(sta_netif, 0), addrStr, sizeof(addrStr)) != NULL); + ChipLogProgress(DeviceLayer, "SLAAC OK: linklocal addr: %s", addrStr); wfx_ipv6_notify(GET_IPV6_SUCCESS); hasNotifiedIPV6 = true; event.eventType = WFX_EVT_STA_DHCP_DONE; @@ -801,7 +765,7 @@ void WfxPostEvent(WfxEvent_t * event) if (status != osOK) { - SILABS_LOG("WfxPostEvent: failed to post event with status: %d", status); + ChipLogError(DeviceLayer, "WfxPostEvent: failed to post event: 0x%lx", static_cast(status)); // TODO: Handle error, requeue event depending on queue size or notify relevant task, Chipdie, etc. } } @@ -829,7 +793,7 @@ void ProcessEvent(WfxEvent_t inEvent) switch (inEvent.eventType) { case WFX_EVT_STA_CONN: - SILABS_LOG("%s: starting LwIP STA", __func__); + ChipLogDetail(DeviceLayer, "WFX_EVT_STA_CONN"); wfx_rsi.dev_state |= WFX_RSI_ST_STA_CONNECTED; ResetDHCPNotificationFlags(); wfx_lwip_set_sta_link_up(); @@ -840,10 +804,10 @@ void ProcessEvent(WfxEvent_t inEvent) // is independant of IP connectivity. break; case WFX_EVT_STA_DISCONN: + ChipLogDetail(DeviceLayer, "WFX_EVT_STA_DISCONN"); // TODO: This event is not being posted anywhere, seems to be a dead code or we are missing something wfx_rsi.dev_state &= ~(WFX_RSI_ST_STA_READY | WFX_RSI_ST_STA_CONNECTING | WFX_RSI_ST_STA_CONNECTED | WFX_RSI_ST_STA_DHCP_DONE); - SILABS_LOG("%s: disconnect notify", __func__); /* TODO: Implement disconnect notify */ ResetDHCPNotificationFlags(); wfx_lwip_set_sta_link_down(); // Internally dhcpclient_poll(netif) -> @@ -863,9 +827,9 @@ void ProcessEvent(WfxEvent_t inEvent) #ifdef SL_WFX_CONFIG_SCAN if (!(wfx_rsi.dev_state & WFX_RSI_ST_SCANSTARTED)) { - SILABS_LOG("%s: start SSID scan", __func__); + ChipLogDetail(DeviceLayer, "WFX_EVT_SCAN"); sl_wifi_scan_configuration_t wifi_scan_configuration; - memset(&wifi_scan_configuration, 0, sizeof(sl_wifi_scan_configuration_t)); + memset(&wifi_scan_configuration, 0, sizeof(wifi_scan_configuration)); // TODO: Add scan logic sl_wifi_advanced_scan_configuration_t advanced_scan_configuration = { 0 }; @@ -879,7 +843,7 @@ void ProcessEvent(WfxEvent_t inEvent) if (SL_STATUS_OK != status) { // TODO: Seems like Chipdie should be called here, the device should be initialized here - SILABS_LOG("Failed to set advanced scan configuration with status: %d", status); + ChipLogError(DeviceLayer, "sl_wifi_set_advanced_scan_configuration failed: 0x%lx", static_cast(status)); return; } @@ -942,13 +906,13 @@ void wfx_rsi_task(void * arg) WfxEvent_t wfxEvent; if (status != RSI_SUCCESS) { - SILABS_LOG("wfx_rsi_task: error: wfx_rsi_init with status: %02x", status); + ChipLogError(DeviceLayer, "wfx_rsi_task: wfx_rsi_init failed: 0x%lx", static_cast(status)); return; } wfx_lwip_start(); wfx_started_notify(); - SILABS_LOG("wfx_rsi_task: starting event loop"); + ChipLogDetail(DeviceLayer, "wfx_rsi_task: starting event loop"); for (;;) { status = osMessageQueueGet(sWifiEventQueue, &wfxEvent, NULL, osWaitForever); @@ -958,8 +922,7 @@ void wfx_rsi_task(void * arg) } else { - // TODO: Everywhere in this file(and related) SILABS_LOG ---> Chiplog - SILABS_LOG("Failed to get event with status: %x", status); + ChipLogError(DeviceLayer, "wfx_rsi_task: get event failed: 0x%lx", static_cast(status)); } } } @@ -982,8 +945,8 @@ void wfx_dhcp_got_ipv4(uint32_t ip) wfx_rsi.ip4_addr[1] = (ip >> 8) & HEX_VALUE_FF; wfx_rsi.ip4_addr[2] = (ip >> 16) & HEX_VALUE_FF; wfx_rsi.ip4_addr[3] = (ip >> 24) & HEX_VALUE_FF; - SILABS_LOG("%s: DHCP OK: IP=%d.%d.%d.%d", __func__, wfx_rsi.ip4_addr[0], wfx_rsi.ip4_addr[1], wfx_rsi.ip4_addr[2], - wfx_rsi.ip4_addr[3]); + ChipLogDetail(DeviceLayer, "DHCP OK: IP=%d.%d.%d.%d", wfx_rsi.ip4_addr[0], wfx_rsi.ip4_addr[1], wfx_rsi.ip4_addr[2], + wfx_rsi.ip4_addr[3]); /* Notify the Connectivity Manager - via the app */ wfx_rsi.dev_state |= WFX_RSI_ST_STA_DHCP_DONE; wfx_ip_changed_notify(IP_STATUS_SUCCESS); diff --git a/examples/platform/silabs/efr32/rs911x/rsi_if.c b/examples/platform/silabs/efr32/rs911x/rsi_if.c index 3596b098b7a1ca..a08e2a2f292de1 100644 --- a/examples/platform/silabs/efr32/rs911x/rsi_if.c +++ b/examples/platform/silabs/efr32/rs911x/rsi_if.c @@ -142,7 +142,7 @@ int32_t wfx_rsi_get_ap_info(wfx_wifi_scan_result_t * ap) uint8_t rssi; ap->security = wfx_rsi.sec.security; ap->chan = wfx_rsi.ap_chan; - memcpy(&ap->bssid[0], &wfx_rsi.ap_mac.octet[0], BSSID_MAX_STR_LEN); + memcpy(&ap->bssid[0], &wfx_rsi.ap_mac.octet[0], BSSID_LEN); status = rsi_wlan_get(RSI_RSSI, &rssi, sizeof(rssi)); if (status == RSI_SUCCESS) { @@ -493,7 +493,7 @@ static void wfx_rsi_save_ap_info() // translation } wfx_rsi.sec.security = WFX_SEC_UNSPECIFIED; wfx_rsi.ap_chan = rsp.scan_info->rf_channel; - memcpy(&wfx_rsi.ap_mac.octet[0], &rsp.scan_info->bssid[0], BSSID_MAX_STR_LEN); + memcpy(&wfx_rsi.ap_mac.octet[0], &rsp.scan_info->bssid[0], BSSID_LEN); switch (rsp.scan_info->security_mode) { @@ -753,9 +753,9 @@ void ProcessEvent(WfxEvent_t inEvent) strncpy(ap.ssid, (char *) scan->ssid, MIN(sizeof(ap.ssid), sizeof(scan->ssid))); ap.security = scan->security_mode; ap.rssi = (-1) * scan->rssi_val; - configASSERT(sizeof(ap.bssid) >= BSSID_MAX_STR_LEN); - configASSERT(sizeof(scan->bssid) >= BSSID_MAX_STR_LEN); - memcpy(ap.bssid, scan->bssid, BSSID_MAX_STR_LEN); + configASSERT(sizeof(ap.bssid) >= BSSID_LEN); + configASSERT(sizeof(scan->bssid) >= BSSID_LEN); + memcpy(ap.bssid, scan->bssid, BSSID_LEN); (*wfx_rsi.scan_cb)(&ap); if (wfx_rsi.scan_ssid) diff --git a/examples/platform/silabs/efr32/wf200/host_if.cpp b/examples/platform/silabs/efr32/wf200/host_if.cpp index 041a1778421ed3..ac3ad07773d9d3 100644 --- a/examples/platform/silabs/efr32/wf200/host_if.cpp +++ b/examples/platform/silabs/efr32/wf200/host_if.cpp @@ -335,7 +335,7 @@ static void sl_wfx_scan_result_callback(sl_wfx_scan_result_ind_body_t * scan_res } ap->scan.chan = scan_result->channel; ap->scan.rssi = scan_result->rcpi; - memcpy(&ap->scan.bssid[0], &scan_result->mac[0], BSSID_MAX_STR_LEN); + memcpy(&ap->scan.bssid[0], &scan_result->mac[0], BSSID_LEN); scan_count++; } } diff --git a/examples/thermostat/nxp/zephyr/.gitignore b/examples/thermostat/nxp/zephyr/.gitignore new file mode 100644 index 00000000000000..84c048a73cc2e5 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/examples/thermostat/nxp/zephyr/CMakeLists.txt b/examples/thermostat/nxp/zephyr/CMakeLists.txt new file mode 100644 index 00000000000000..2b0fb87a55e7f9 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/CMakeLists.txt @@ -0,0 +1,104 @@ +# +# Copyright (c) 2023-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. +# +cmake_minimum_required(VERSION 3.13.1) + +get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connectedhomeip REALPATH) +get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) +get_filename_component(ALL_CLUSTERS_COMMON_DIR ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) +get_filename_component(THERMOSTAT_NXP_COMMON_DIR ${CHIP_ROOT}/examples/thermostat/nxp/common REALPATH) +get_filename_component(EXAMPLE_PLATFORM_NXP_COMMON_DIR ${CHIP_ROOT}/examples/platform/nxp/common REALPATH) +get_filename_component(EXAMPLE_PLATFORM_NXP_ZEPHYR_DIR ${CHIP_ROOT}/examples/platform/nxp/zephyr REALPATH) + +# Perform common operations like detecting extra overlays in the platform folder for the target board +# This must be called before find_package(Zephyr) +include(${CHIP_ROOT}/config/nxp/app/pre-zephyr.cmake) + +list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nxp/chip-module) +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) + +# -Wmaybe-uninitialized has too many false positives, including on std::optional +# and chip::Optional. Make it nonfatal. +# +# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635 +target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) +target_compile_options(app PRIVATE -Werror PRIVATE -Wno-error=format) + +project(chip-nxp-all-clusters-app-example) + +include(${CHIP_ROOT}/config/nxp/app/enable-gnu-std.cmake) +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) + +target_include_directories(app + PRIVATE + ${THERMOSTAT_NXP_COMMON_DIR}/main/include + ${ALL_CLUSTERS_COMMON_DIR}/include + ${GEN_DIR}/app-common + ${GEN_DIR}/all-clusters-app + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_manager/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/icd/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_callbacks/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/factory_data/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/include +) + +target_sources(app + PRIVATE + main/main.cpp + ${THERMOSTAT_NXP_COMMON_DIR}/main/AppTask.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_manager/source/CHIPDeviceManager.cpp + ${THERMOSTAT_NXP_COMMON_DIR}/main/DeviceCallbacks.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_callbacks/source/CommonDeviceCallbacks.cpp + ${THERMOSTAT_NXP_COMMON_DIR}/main/ZclCallbacks.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/source/AppTaskBase.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/source/AppTaskZephyr.cpp + ${EXAMPLE_PLATFORM_NXP_ZEPHYR_DIR}/factory_data/source/AppFactoryDataExample.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/icd/source/ICDUtil.cpp +) + +target_compile_definitions(app PUBLIC + "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/zephyr/FactoryDataProviderImpl.h\"" +) + +if(CONFIG_CHIP_OTA_REQUESTOR) + target_sources(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/source/OTARequestorInitiatorCommon.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/source/OTARequestorInitiatorZephyr.cpp + ) + target_include_directories(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/include/ + ) +endif() + +chip_configure_data_model(app + INCLUDE_SERVER + ZAP_FILE ${ALL_CLUSTERS_COMMON_DIR}/../../thermostat/nxp/zap/thermostat_matter_wifi.zap +) + +if(CONFIG_CHIP_LIB_SHELL) + target_compile_definitions(app PRIVATE ENABLE_CHIP_SHELL) + target_include_directories(app PRIVATE + ${CHIP_ROOT}/examples/shell/shell_common/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/include + ) + target_sources(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/source/AppCLIBase.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/source/AppCLIZephyr.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_misc.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_otcli.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_server.cpp + ) +endif() diff --git a/examples/thermostat/nxp/zephyr/Kconfig b/examples/thermostat/nxp/zephyr/Kconfig new file mode 100644 index 00000000000000..72e90f047d1e38 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/Kconfig @@ -0,0 +1,20 @@ +# +# 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. +# +mainmenu "Matter NXP Thermostat Example Application" + +rsource "../../../../config/nxp/chip-module/Kconfig.features" +rsource "../../../../config/nxp/chip-module/Kconfig.defaults" +source "Kconfig.zephyr" diff --git a/examples/thermostat/nxp/zephyr/README.md b/examples/thermostat/nxp/zephyr/README.md new file mode 100644 index 00000000000000..84d3fb9e59cf01 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/README.md @@ -0,0 +1,4 @@ +# CHIP NXP Zephyr Thermostat Application + +All instructions describing how to use a Matter application on NXP Zephyr can be +found in [README.md](../../../all-clusters-app/nxp/zephyr/README.md) root readme diff --git a/examples/thermostat/nxp/zephyr/boards/rd_rw612_bga.overlay b/examples/thermostat/nxp/zephyr/boards/rd_rw612_bga.overlay new file mode 100644 index 00000000000000..86bb20739527cd --- /dev/null +++ b/examples/thermostat/nxp/zephyr/boards/rd_rw612_bga.overlay @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023-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. + */ + +/ { + chosen { + zephyr,console = &flexcomm0; + zephyr,shell-uart = &flexcomm3; + }; +}; + +&flexcomm0 { + compatible = "nxp,lpc-usart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm0_usart>; + pinctrl-names = "default"; +}; + +&flexcomm3 { + compatible = "nxp,lpc-usart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm3_usart>; + pinctrl-names = "default"; +}; diff --git a/examples/thermostat/nxp/zephyr/boards/rd_rw612_bga_fdata.conf b/examples/thermostat/nxp/zephyr/boards/rd_rw612_bga_fdata.conf new file mode 100644 index 00000000000000..73d139c3948d95 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/boards/rd_rw612_bga_fdata.conf @@ -0,0 +1,23 @@ +# +# Copyright (c) 2023-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. +# + +CONFIG_SETTINGS_NVS_SECTOR_COUNT=16 + +# 0xA226 +CONFIG_CHIP_DEVICE_PRODUCT_ID=41510 +CONFIG_CHIP_DEVICE_PRODUCT_URL="https://www.nxp.com/products/wireless-connectivity/wi-fi-plus-bluetooth-plus-802-15-4/wireless-mcu-with-integrated-tri-radio-1x1-wi-fi-6-plus-bluetooth-low-energy-5-3-802-15-4:RW612" +CONFIG_CHIP_DEVICE_PRODUCT_LABEL="RW612" +CONFIG_CHIP_DEVICE_PART_NUMBER="RW612" diff --git a/examples/thermostat/nxp/zephyr/main/include/CHIPProjectConfig.h b/examples/thermostat/nxp/zephyr/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..84c57df1ea140d --- /dev/null +++ b/examples/thermostat/nxp/zephyr/main/include/CHIPProjectConfig.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023-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. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR CONFIG_CHIP_DEVICE_DISCRIMINATOR + +// All clusters app has 3 group endpoints. This needs to defined here so that +// CHIP_CONFIG_MAX_GROUPS_PER_FABRIC is properly configured. +#define CHIP_CONFIG_MAX_GROUP_ENDPOINTS_PER_FABRIC 3 diff --git a/examples/thermostat/nxp/zephyr/main/main.cpp b/examples/thermostat/nxp/zephyr/main/main.cpp new file mode 100644 index 00000000000000..9be47dfe0a95d8 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/main/main.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023-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 "AppTask.h" + +#include + +LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); + +using namespace ::chip; + +int main() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + if (err == CHIP_NO_ERROR) + { + err = chip::NXP::App::GetAppTask().Start(); + } + + LOG_ERR("Exited with code %" CHIP_ERROR_FORMAT, err.Format()); + return err == CHIP_NO_ERROR ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/thermostat/nxp/zephyr/prj.conf b/examples/thermostat/nxp/zephyr/prj.conf new file mode 100644 index 00000000000000..8bb5bd9f275756 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/prj.conf @@ -0,0 +1,59 @@ +# +# Copyright (c) 2023-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. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_STD_CPP17=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y +# CHIP PID: 32769 == 0x8001 (all-clusters-app) +CONFIG_CHIP_DEVICE_PRODUCT_ID=32769 +CONFIG_CHIP_DEVICE_PRODUCT_NAME="Thermostat" +CONFIG_CHIP_DEVICE_DISCRIMINATOR=0x800 + +# Enable MbedTLS PSA - heavily experimental, not thread safe yet +# CONFIG_CHIP_CRYPTO_PSA=y + +# Bluetooth overrides +CONFIG_BT_DEVICE_NAME="Thermostat" + +# Additional configs for debbugging experience. +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y + +CONFIG_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_THREAD_INFO=y +# use this config if stepping during debug session is not consistent +# CONFIG_NO_OPTIMIZATIONS=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_ASSERT=y +# by default west will generate the full assembly output, which can take several minutes when binaries are large +CONFIG_OUTPUT_DISASSEMBLY=n +# embedded thread analyzer with thread statistics (stack usage, cpu usage...) +# CONFIG_THREAD_ANALYZER=y +# CONFIG_THREAD_ANALYZER_USE_PRINTK=y +# CONFIG_THREAD_ANALYZER_AUTO=y + +# enable Matter CLI +CONFIG_CHIP_LIB_SHELL=y +# enable NET commands if desired +#CONFIG_NET_SHELL=y +CONFIG_CHIP_STATISTICS=y diff --git a/examples/thermostat/nxp/zephyr/prj_fdata.conf b/examples/thermostat/nxp/zephyr/prj_fdata.conf new file mode 100644 index 00000000000000..ee559b42ed9a71 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/prj_fdata.conf @@ -0,0 +1,80 @@ +# +# Copyright (c) 2023-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. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_STD_CPP17=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable MbedTLS PSA - heavily experimental, not thread safe yet +# CONFIG_CHIP_CRYPTO_PSA=y + +# Bluetooth overrides +CONFIG_BT_DEVICE_NAME="Thermostat" + +# enable Matter CLI +CONFIG_CHIP_LIB_SHELL=y +CONFIG_CHIP_STATISTICS=y + +# Factory data configuration +CONFIG_CHIP_DEVICE_VENDOR_ID=4151 +CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xA00 +CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE=14014 +CONFIG_CHIP_DEVICE_PRODUCT_NAME="Thermostat" +CONFIG_CHIP_DEVICE_TYPE=769 +CONFIG_CHIP_DEVICE_MANUFACTURING_DATE="2023-01-01" +CONFIG_CHIP_DEVICE_SERIAL_NUMBER="12345678" +CONFIG_CHIP_DEVICE_PRODUCT_COLOR="Green" +CONFIG_CHIP_DEVICE_PRODUCT_FINISH="Matte" + +# Use factory data provider for device info +CONFIG_CHIP_FACTORY_DATA=y +# Generate factor data raw binary during the build process +# CONFIG_CHIP_FACTORY_DATA_BUILD=y +# Generate test certificates for factory data during the build process +# CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED=y +# Spake2p verifier will be generated during factory data generation +# CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER=y + +# Example of using pre-generated certificates +# CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_USER=y +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_CD_CERT="/Chip-Test-CD-1037-A226.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_CERT="/Chip-DAC-NXP-1037-A226-Cert.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_KEY="/Chip-DAC-NXP-1037-A226-Key.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_PAI_CERT="/Chip-PAI-NXP-1037-A226-Cert.der" + +# Additional configs for debbugging experience. +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y + +CONFIG_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_THREAD_INFO=y +# use this config if stepping during debug session is not consistent +# CONFIG_NO_OPTIMIZATIONS=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_ASSERT=y +# by default west will generate the full assembly output, which can take several minutes when binaries are large +CONFIG_OUTPUT_DISASSEMBLY=n +# embedded thread analyzer with thread statistics (stack usage, cpu usage...) +# CONFIG_THREAD_ANALYZER=y +# CONFIG_THREAD_ANALYZER_USE_PRINTK=y +# CONFIG_THREAD_ANALYZER_AUTO=y diff --git a/examples/thermostat/nxp/zephyr/prj_ota.conf b/examples/thermostat/nxp/zephyr/prj_ota.conf new file mode 100644 index 00000000000000..bdc65e94fabf70 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/prj_ota.conf @@ -0,0 +1,31 @@ +# +# 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. +# + +# Options needed for OTA are located on this file +# This file should contain only options specific for this sample +# or overrides the default ones. + +CONFIG_CHIP_OTA_REQUESTOR=y + +# To generate an OTA image based on the application +CONFIG_CHIP_OTA_IMAGE_BUILD=y + +# By default, MCUBOOT bootloader uses a signature key provided in their repository. +# Change the key to the appropriate one. +# Note: You need to use the same signature key used by MCUBOOT, i.e BOOT_SIGNATURE_KEY_FILE. +# Default CONFIG_BOOT_SIGNATURE_KEY_FILE is defined in config/nxp/app/bootloader.conf +CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="./bootloader/mcuboot/root-rsa-2048.pem" diff --git a/examples/thermostat/nxp/zephyr/third_party/connectedhomeip b/examples/thermostat/nxp/zephyr/third_party/connectedhomeip new file mode 120000 index 00000000000000..3efed95be5dbe9 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../ \ No newline at end of file diff --git a/examples/tv-app/android/App/content-app/src/main/AndroidManifest.xml b/examples/tv-app/android/App/content-app/src/main/AndroidManifest.xml index 61d036e0a90ef4..fff52c4b59db7e 100644 --- a/examples/tv-app/android/App/content-app/src/main/AndroidManifest.xml +++ b/examples/tv-app/android/App/content-app/src/main/AndroidManifest.xml @@ -19,7 +19,7 @@ - + diff --git a/examples/tv-app/android/App/platform-app/src/main/AndroidManifest.xml b/examples/tv-app/android/App/platform-app/src/main/AndroidManifest.xml index b6e00cd75d0365..476faa2030c7a2 100644 --- a/examples/tv-app/android/App/platform-app/src/main/AndroidManifest.xml +++ b/examples/tv-app/android/App/platform-app/src/main/AndroidManifest.xml @@ -26,6 +26,9 @@ tools:ignore="QueryAllPackagesPermission" /> + + + tasks = activityManager.getRunningTasks(1); + if (tasks != null && !tasks.isEmpty()) { + ActivityManager.RunningTaskInfo taskInfo = tasks.get(0); + String packageName = + taskInfo.topActivity != null ? taskInfo.topActivity.getPackageName() : ""; + return packageName.equals(contentAppPackageName); + } + return false; + } + public String sendCommand(int endpointId, long clusterId, long commandId, String commandPayload) { Log.d(TAG, "Received a command for endpointId " + endpointId + ". Message " + commandPayload); @@ -26,6 +55,17 @@ public String sendCommand(int endpointId, long clusterId, long commandId, String ContentAppDiscoveryService.getReceiverInstance().getDiscoveredContentApps().values(), endpointId); if (discoveredApp != null) { + // Intercept NavigateTarget and LaunchContent commands and launch content app if necessary + if (isForegroundCommand(clusterId, commandId)) { + // Check if contentapp main/launch activity is already in foreground before launching. + if (!isAppInForeground(discoveredApp.getAppName())) { + Intent launchIntent = + context.getPackageManager().getLaunchIntentForPackage(discoveredApp.getAppName()); + if (launchIntent != null) { + context.startActivity(launchIntent); + } + } + } Log.d(TAG, "Sending a command for endpointId " + endpointId + ". Message " + commandPayload); return ContentAppAgentService.sendCommand( context, discoveredApp.getAppName(), clusterId, commandId, commandPayload); diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/model/ContentApp.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/model/ContentApp.java index e30a75a00d98b2..0cd12b404d6fcf 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/model/ContentApp.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/model/ContentApp.java @@ -25,6 +25,7 @@ public ContentApp( this.vendorId = vendorId; this.productId = productId; this.version = version; + this.supportedClusters = Collections.EMPTY_SET; } public ContentApp( @@ -67,9 +68,7 @@ public void setEndpointId(int endpoint) { } public Set getSupportedClusters() { - return supportedClusters != null - ? Collections.unmodifiableSet(supportedClusters) - : Collections.EMPTY_SET; + return Collections.unmodifiableSet(supportedClusters); } public String getVersion() { diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java index f587905fb09145..227ea9326be538 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java @@ -4,13 +4,18 @@ import android.content.SharedPreferences; import android.util.JsonReader; import android.util.JsonWriter; +import com.matter.tv.app.api.SupportedCluster; import com.matter.tv.server.model.ContentApp; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Set; public class EndpointsDataStore { @@ -21,6 +26,11 @@ public class EndpointsDataStore { private static final String KEY_PRODUCTID = "PID"; private static final String KEY_VERSION = "VER"; private static final String KEY_ENDPOINTID = "EPID"; + private static final String KEY_SUPPORTED_CLUSTERS = "supportedClusters"; + private static final String KEY_CLUSTER_IDENTIFIER = "clusterIdentifier"; + private static final String KEY_FEATURES = "features"; + private static final String KEY_OPTIONAL_COMMAND_IDENTIFIERS = "optionalCommandIdentifiers"; + private static final String KEY_OPTIONAL_ATTRIBUTES_IDENTIFIERS = "optionalAttributesIdentifiers"; private static EndpointsDataStore instance; private final SharedPreferences discoveredEndpoints; Map persistedContentApps = new HashMap<>(); @@ -57,19 +67,20 @@ private String serializeContentApp(ContentApp app) { StringWriter stringWriter = new StringWriter(); JsonWriter jsonWriter = new JsonWriter(stringWriter); try { - jsonWriter - .beginObject() - .name(KEY_VENDORID) - .value(app.getVendorId()) - .name(KEY_VENDORNAME) - .value(app.getVendorName()) - .name(KEY_PRODUCTID) - .value(app.getProductId()) - .name(KEY_VERSION) - .value(app.getVersion()) - .name(KEY_ENDPOINTID) - .value(app.getEndpointId()) - .endObject(); + jsonWriter.beginObject(); + jsonWriter.name(KEY_VENDORID); + jsonWriter.value(app.getVendorId()); + jsonWriter.name(KEY_VENDORNAME); + jsonWriter.value(app.getVendorName()); + jsonWriter.name(KEY_PRODUCTID); + jsonWriter.value(app.getProductId()); + jsonWriter.name(KEY_VERSION); + jsonWriter.value(app.getVersion()); + jsonWriter.name(KEY_ENDPOINTID); + jsonWriter.value(app.getEndpointId()); + jsonWriter.name(KEY_SUPPORTED_CLUSTERS); + serializeSupportedClusters(jsonWriter, app.getSupportedClusters()); + jsonWriter.endObject(); jsonWriter.flush(); jsonWriter.close(); } catch (IOException e) { @@ -88,6 +99,7 @@ private ContentApp deserializeContentApp(String appName, String appMetadata) { int vendorId = 0; int productId = 0; int endpoint = ContentApp.INVALID_ENDPOINTID; + Set supportedClusters = new HashSet<>(); while (jsonReader.hasNext()) { String name = jsonReader.nextName(); switch (name) { @@ -106,9 +118,12 @@ private ContentApp deserializeContentApp(String appName, String appMetadata) { case KEY_ENDPOINTID: endpoint = jsonReader.nextInt(); break; + case KEY_SUPPORTED_CLUSTERS: + supportedClusters = deserializeSupportedClusters(jsonReader); + break; } } - app = new ContentApp(appName, vendorName, vendorId, productId, version); + app = new ContentApp(appName, vendorName, vendorId, productId, version, supportedClusters); jsonReader.endObject(); jsonReader.close(); } catch (IOException e) { @@ -116,4 +131,86 @@ private ContentApp deserializeContentApp(String appName, String appMetadata) { } return app; } + + private void serializeSupportedClusters( + JsonWriter jsonWriter, Set supportedClusters) throws IOException { + if (supportedClusters != null) { + jsonWriter.beginArray(); + for (SupportedCluster supportedCluster : supportedClusters) { + if (supportedCluster != null) { + serializeSupportedCluster(jsonWriter, supportedCluster); + } + } + jsonWriter.endArray(); + } + } + + private Set deserializeSupportedClusters(JsonReader jsonReader) + throws IOException { + Set supportedClusters = new HashSet<>(); + jsonReader.beginArray(); + while (jsonReader.hasNext()) { + supportedClusters.add(deserializeSupportedCluster(jsonReader)); + } + jsonReader.endArray(); + return supportedClusters; + } + + private void serializeSupportedCluster(JsonWriter jsonWriter, SupportedCluster supportedCluster) + throws IOException { + jsonWriter.beginObject(); + jsonWriter.name(KEY_CLUSTER_IDENTIFIER); + jsonWriter.value(supportedCluster.clusterIdentifier); + jsonWriter.name(KEY_FEATURES); + jsonWriter.value(supportedCluster.features); + jsonWriter.name(KEY_OPTIONAL_COMMAND_IDENTIFIERS); + serializeIntArray(jsonWriter, supportedCluster.optionalCommandIdentifiers); + jsonWriter.name(KEY_OPTIONAL_ATTRIBUTES_IDENTIFIERS); + serializeIntArray(jsonWriter, supportedCluster.optionalAttributesIdentifiers); + jsonWriter.endObject(); + } + + private SupportedCluster deserializeSupportedCluster(JsonReader jsonReader) throws IOException { + SupportedCluster supportedCluster = new SupportedCluster(); + jsonReader.beginObject(); + while (jsonReader.hasNext()) { + String name = jsonReader.nextName(); + switch (name) { + case KEY_CLUSTER_IDENTIFIER: + supportedCluster.clusterIdentifier = jsonReader.nextInt(); + break; + case KEY_FEATURES: + supportedCluster.features = jsonReader.nextInt(); + break; + case KEY_OPTIONAL_COMMAND_IDENTIFIERS: + supportedCluster.optionalCommandIdentifiers = deserializeIntArray(jsonReader); + break; + case KEY_OPTIONAL_ATTRIBUTES_IDENTIFIERS: + supportedCluster.optionalAttributesIdentifiers = deserializeIntArray(jsonReader); + break; + } + } + jsonReader.endObject(); + return supportedCluster; + } + + private void serializeIntArray(JsonWriter jsonWriter, int[] array) throws IOException { + jsonWriter.beginArray(); + if (array != null) { + for (int value : array) { + jsonWriter.value(value); + } + } + jsonWriter.endArray(); + } + + private int[] deserializeIntArray(JsonReader jsonReader) throws IOException { + List dynamicArray = new ArrayList<>(); + jsonReader.beginArray(); + while (jsonReader.hasNext()) { + dynamicArray.add(jsonReader.nextInt()); + } + jsonReader.endArray(); + return dynamicArray.stream().mapToInt(Integer::intValue).toArray(); + } } diff --git a/examples/tv-app/android/java/AppImpl.cpp b/examples/tv-app/android/java/AppImpl.cpp index 4dfabd03f12ec6..c24e7e537dbb23 100644 --- a/examples/tv-app/android/java/AppImpl.cpp +++ b/examples/tv-app/android/java/AppImpl.cpp @@ -355,6 +355,87 @@ ContentApp * ContentAppFactoryImpl::LoadContentApp(const CatalogVendorApp & vend return nullptr; } +class DevicePairedCommand : public Controller::DevicePairingDelegate +{ +public: + struct CallbackContext + { + uint16_t vendorId; + uint16_t productId; + chip::NodeId nodeId; + + CallbackContext(uint16_t vId, uint16_t pId, chip::NodeId nId) : vendorId(vId), productId(pId), nodeId(nId) {} + }; + DevicePairedCommand(uint16_t vendorId, uint16_t productId, chip::NodeId nodeId) : + mOnDeviceConnectedCallback(OnDeviceConnectedFn, this), mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this) + { + mContext = std::make_shared(vendorId, productId, nodeId); + } + + static void OnDeviceConnectedFn(void * context, chip::Messaging::ExchangeManager & exchangeMgr, + const chip::SessionHandle & sessionHandle) + { + auto * pairingCommand = static_cast(context); + auto cbContext = pairingCommand->mContext; + + if (pairingCommand) + { + ChipLogProgress(DeviceLayer, + "OnDeviceConnectedFn - Updating ACL for node id: " ChipLogFormatX64 + " and vendor id: %d and product id: %d", + ChipLogValueX64(cbContext->nodeId), cbContext->vendorId, cbContext->productId); + + GetCommissionerDiscoveryController()->CommissioningSucceeded(cbContext->vendorId, cbContext->productId, + cbContext->nodeId, exchangeMgr, sessionHandle); + } + } + + static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error) + { + auto * pairingCommand = static_cast(context); + auto cbContext = pairingCommand->mContext; + + if (pairingCommand) + { + ChipLogProgress(DeviceLayer, + "OnDeviceConnectionFailureFn - Not updating ACL for node id: " ChipLogFormatX64 + " and vendor id: %d and product id: %d", + ChipLogValueX64(cbContext->nodeId), cbContext->vendorId, cbContext->productId); + // TODO: Remove Node Id + } + } + + chip::Callback::Callback mOnDeviceConnectedCallback; + chip::Callback::Callback mOnDeviceConnectionFailureCallback; + std::shared_ptr mContext; +}; + +void refreshConnectedClientsAcl(uint16_t vendorId, uint16_t productId, ContentAppImpl * app) +{ + + std::set nodeIds = ContentAppPlatform::GetInstance().GetNodeIdsForContentApp(vendorId, productId); + + for (const auto & allowedVendor : app->GetApplicationBasicDelegate()->GetAllowedVendorList()) + { + std::set tempNodeIds = ContentAppPlatform::GetInstance().GetNodeIdsForAllowVendorId(allowedVendor); + + nodeIds.insert(tempNodeIds.begin(), tempNodeIds.end()); + } + + for (const auto & nodeId : nodeIds) + { + + ChipLogProgress(DeviceLayer, + "Creating Pairing Command with node id: " ChipLogFormatX64 " and vendor id: %d and product id: %d", + ChipLogValueX64(nodeId), vendorId, productId); + + std::shared_ptr pairingCommand = std::make_shared(vendorId, productId, nodeId); + + GetDeviceCommissioner()->GetConnectedDevice(nodeId, &pairingCommand->mOnDeviceConnectedCallback, + &pairingCommand->mOnDeviceConnectionFailureCallback); + } +} + EndpointId ContentAppFactoryImpl::AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName, uint16_t productId, const char * szApplicationVersion, std::vector supportedClusters, jobject manager) @@ -369,6 +450,9 @@ EndpointId ContentAppFactoryImpl::AddContentApp(const char * szVendorName, uint1 app->GetEndpointId()); mContentApps.push_back(app); mDataVersions.push_back(dataVersionBuf); + + refreshConnectedClientsAcl(vendorId, productId, app); + return epId; } @@ -387,6 +471,9 @@ EndpointId ContentAppFactoryImpl::AddContentApp(const char * szVendorName, uint1 app->GetEndpointId()); mContentApps.push_back(app); mDataVersions.push_back(dataVersionBuf); + + refreshConnectedClientsAcl(vendorId, productId, app); + return epId; } diff --git a/examples/tv-app/android/java/TVApp-JNI.cpp b/examples/tv-app/android/java/TVApp-JNI.cpp index 04b5f4199edcaa..65a0a4409e9b8f 100644 --- a/examples/tv-app/android/java/TVApp-JNI.cpp +++ b/examples/tv-app/android/java/TVApp-JNI.cpp @@ -258,6 +258,8 @@ class MyPostCommissioningListener : public PostCommissioningListener // read current binding list chip::Controller::ClusterBase cluster(exchangeMgr, sessionHandle, kTargetBindingClusterEndpointId); + ContentAppPlatform::GetInstance().StoreNodeIdForContentApp(vendorId, productId, nodeId); + cacheContext(vendorId, productId, nodeId, exchangeMgr, sessionHandle); CHIP_ERROR err = diff --git a/examples/tv-app/linux/main.cpp b/examples/tv-app/linux/main.cpp index 29fdd69cb36792..c2055e0abd03f3 100644 --- a/examples/tv-app/linux/main.cpp +++ b/examples/tv-app/linux/main.cpp @@ -45,6 +45,31 @@ void ApplicationInit() ChipLogDetail(DeviceLayer, "TV Linux App: Warning - Fixed Content App Endpoint Not Disabled"); // Can't disable this without breaking CI unit tests that act upon account login cluster (only available on ep3) // emberAfEndpointEnableDisable(3, false); + +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + // Install Content Apps + ContentAppFactoryImpl * factory = GetContentAppFactoryImpl(); + + // Content App 1 + constexpr uint16_t kApp1VendorId = 65521; + constexpr uint16_t kApp1ProductId = 32769; + factory->InstallContentApp(kApp1VendorId, kApp1ProductId); + + // Content App 2 + constexpr uint16_t kApp2VendorId = 1; + constexpr uint16_t kApp2ProductId = 11; + factory->InstallContentApp(kApp2VendorId, kApp2ProductId); + + // Content App 3 + constexpr uint16_t kApp3VendorId = 9050; + constexpr uint16_t kApp3ProductId = 22; + factory->InstallContentApp(kApp3VendorId, kApp3ProductId); + + // Content App 4 + constexpr uint16_t kApp4VendorId = 1111; + constexpr uint16_t kApp4ProductId = 22; + factory->InstallContentApp(kApp4VendorId, kApp4ProductId); +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED } void ApplicationShutdown() {} diff --git a/examples/tv-app/tv-common/shell/AppTvShellCommands.cpp b/examples/tv-app/tv-common/shell/AppTvShellCommands.cpp index b39e84ad40f89a..5125ebbbbd7ecd 100644 --- a/examples/tv-app/tv-common/shell/AppTvShellCommands.cpp +++ b/examples/tv-app/tv-common/shell/AppTvShellCommands.cpp @@ -209,6 +209,10 @@ static CHIP_ERROR PrintAllCommands() #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE streamer_printf(sout, " print-app-access Print all ACLs for app platform fabric. Usage: app print-app-access\r\n"); streamer_printf(sout, " remove-app-access Remove all ACLs for app platform fabric. Usage: app remove-app-access\r\n"); + streamer_printf( + sout, + " print-installed-apps Print all installed content apps with their endpoints. Usage: app print-installed-apps\r\n"); + streamer_printf(sout, " commission Commission given udc-entry using given pincode from corresponding app. Usage: " "app commission 0\r\n"); @@ -436,6 +440,13 @@ static CHIP_ERROR AppPlatformHandler(int argc, char ** argv) Access::GetAccessControl().DeleteAllEntriesForFabric(GetDeviceCommissioner()->GetFabricIndex()); return CHIP_NO_ERROR; } + else if (strcmp(argv[0], "print-installed-apps") == 0) + { + ContentAppFactoryImpl * factory = GetContentAppFactoryImpl(); + factory->LogInstalledApps(); + + return CHIP_NO_ERROR; + } else if (strcmp(argv[0], "commission") == 0) { if (argc < 2) diff --git a/examples/tv-app/tv-common/src/AppTv.cpp b/examples/tv-app/tv-common/src/AppTv.cpp index 03422c3fa462e7..8d81d9cf6c2c5c 100644 --- a/examples/tv-app/tv-common/src/AppTv.cpp +++ b/examples/tv-app/tv-common/src/AppTv.cpp @@ -164,6 +164,8 @@ class MyPostCommissioningListener : public PostCommissioningListener // read current binding list chip::Controller::ClusterBase cluster(exchangeMgr, sessionHandle, kTargetBindingClusterEndpointId); + ContentAppPlatform::GetInstance().StoreNodeIdForContentApp(vendorId, productId, nodeId); + cacheContext(vendorId, productId, nodeId, exchangeMgr, sessionHandle); CHIP_ERROR err = @@ -565,6 +567,63 @@ void ContentAppFactoryImpl::AddAdminVendorId(uint16_t vendorId) mAdminVendorIds.push_back(vendorId); } +#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE +class DevicePairedCommand : public Controller::DevicePairingDelegate +{ +public: + struct CallbackContext + { + uint16_t vendorId; + uint16_t productId; + chip::NodeId nodeId; + + CallbackContext(uint16_t vId, uint16_t pId, chip::NodeId nId) : vendorId(vId), productId(pId), nodeId(nId) {} + }; + DevicePairedCommand(uint16_t vendorId, uint16_t productId, chip::NodeId nodeId) : + mOnDeviceConnectedCallback(OnDeviceConnectedFn, this), mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this) + { + mContext = std::make_shared(vendorId, productId, nodeId); + } + + static void OnDeviceConnectedFn(void * context, chip::Messaging::ExchangeManager & exchangeMgr, + const chip::SessionHandle & sessionHandle) + { + auto * pairingCommand = static_cast(context); + auto cbContext = pairingCommand->mContext; + + if (pairingCommand) + { + ChipLogProgress(DeviceLayer, + "OnDeviceConnectedFn - Updating ACL for node id: " ChipLogFormatX64 + " and vendor id: %d and product id: %d", + ChipLogValueX64(cbContext->nodeId), cbContext->vendorId, cbContext->productId); + + GetCommissionerDiscoveryController()->CommissioningSucceeded(cbContext->vendorId, cbContext->productId, + cbContext->nodeId, exchangeMgr, sessionHandle); + } + } + + static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error) + { + auto * pairingCommand = static_cast(context); + auto cbContext = pairingCommand->mContext; + + if (pairingCommand) + { + ChipLogProgress(DeviceLayer, + "OnDeviceConnectionFailureFn - Not updating ACL for node id: " ChipLogFormatX64 + " and vendor id: %d and product id: %d", + ChipLogValueX64(cbContext->nodeId), cbContext->vendorId, cbContext->productId); + // TODO: Remove Node Id + } + } + + chip::Callback::Callback mOnDeviceConnectedCallback; + chip::Callback::Callback mOnDeviceConnectionFailureCallback; + std::shared_ptr mContext; +}; +#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + void ContentAppFactoryImpl::InstallContentApp(uint16_t vendorId, uint16_t productId) { auto make_default_supported_clusters = []() { @@ -605,6 +664,46 @@ void ContentAppFactoryImpl::InstallContentApp(uint16_t vendorId, uint16_t produc make_default_supported_clusters()); mContentApps.emplace_back(std::move(ptr)); } + +#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + // Get the list of node ids + std::set nodeIds = ContentAppPlatform::GetInstance().GetNodeIdsForContentApp(vendorId, productId); + + // update ACLs + for (auto & contentApp : mContentApps) + { + auto app = contentApp.get(); + + if (app->MatchesPidVid(productId, vendorId)) + { + CatalogVendorApp vendorApp = app->GetApplicationBasicDelegate()->GetCatalogVendorApp(); + + GetContentAppFactoryImpl()->LoadContentApp(vendorApp); + } + + // update the list of node ids with content apps allowed vendor list + for (const auto & allowedVendor : app->GetApplicationBasicDelegate()->GetAllowedVendorList()) + { + std::set tempNodeIds = ContentAppPlatform::GetInstance().GetNodeIdsForAllowVendorId(allowedVendor); + + nodeIds.insert(tempNodeIds.begin(), tempNodeIds.end()); + } + } + + // refresh ACLs + for (const auto & nodeId : nodeIds) + { + + ChipLogProgress(DeviceLayer, + "Creating Pairing Command with node id: " ChipLogFormatX64 " and vendor id: %d and product id: %d", + ChipLogValueX64(nodeId), vendorId, productId); + + std::shared_ptr pairingCommand = std::make_shared(vendorId, productId, nodeId); + + GetDeviceCommissioner()->GetConnectedDevice(nodeId, &pairingCommand->mOnDeviceConnectedCallback, + &pairingCommand->mOnDeviceConnectionFailureCallback); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE } bool ContentAppFactoryImpl::UninstallContentApp(uint16_t vendorId, uint16_t productId) @@ -625,8 +724,9 @@ bool ContentAppFactoryImpl::UninstallContentApp(uint16_t vendorId, uint16_t prod ChipLogProgress(DeviceLayer, "Found an app vid=%d pid=%d. Uninstalling it.", app->GetApplicationBasicDelegate()->HandleGetVendorId(), app->GetApplicationBasicDelegate()->HandleGetProductId()); + EndpointId removedEndpointID = ContentAppPlatform::GetInstance().RemoveContentApp(app); + ChipLogProgress(DeviceLayer, "Removed content app at endpoint id: %d", removedEndpointID); mContentApps.erase(mContentApps.begin() + index); - // TODO: call ContentAppPlatform->RemoveContentApp(ids...) return true; } @@ -701,22 +801,8 @@ std::list ContentAppFactoryImpl::GetAllowedClusterListForStaticEndpoi CHIP_ERROR AppTvInit() { #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED - // test data for apps - constexpr uint16_t kApp1VendorId = 1; - constexpr uint16_t kApp1ProductId = 11; - constexpr uint16_t kApp2VendorId = 65521; - constexpr uint16_t kApp2ProductId = 32769; - constexpr uint16_t kApp3VendorId = 9050; - constexpr uint16_t kApp3ProductId = 22; - constexpr uint16_t kApp4VendorId = 1111; - constexpr uint16_t kApp4ProductId = 22; - ContentAppPlatform::GetInstance().SetupAppPlatform(); ContentAppPlatform::GetInstance().SetContentAppFactory(&gFactory); - gFactory.InstallContentApp(kApp1VendorId, kApp1ProductId); - gFactory.InstallContentApp(kApp2VendorId, kApp2ProductId); - gFactory.InstallContentApp(kApp3VendorId, kApp3ProductId); - gFactory.InstallContentApp(kApp4VendorId, kApp4ProductId); uint16_t value; if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(value) != CHIP_NO_ERROR) { diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 0a72b3733a96d1..97f8e90af507d5 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -28,7 +28,7 @@ from builders.mw320 import MW320App, MW320Builder from builders.nrf import NrfApp, NrfBoard, NrfConnectBuilder from builders.nuttx import NuttXApp, NuttXBoard, NuttXBuilder -from builders.nxp import NxpApp, NxpBoard, NxpBuilder +from builders.nxp import NxpApp, NxpBoard, NxpBuilder, NxpOsUsed from builders.openiotsdk import OpenIotSdkApp, OpenIotSdkBuilder, OpenIotSdkCryptoBackend from builders.qpg import QpgApp, QpgBoard, QpgBuilder from builders.rw61x import RW61XApp, RW61XBuilder @@ -499,13 +499,23 @@ def BuildNxpTarget(): # boards target.AppendFixedTargets([ TargetPart('k32w0', board=NxpBoard.K32W0), - TargetPart('k32w1', board=NxpBoard.K32W1) + TargetPart('k32w1', board=NxpBoard.K32W1), + TargetPart('rw61x', board=NxpBoard.RW61X) + ]) + + # OS + target.AppendFixedTargets([ + TargetPart('zephyr', os_env=NxpOsUsed.ZEPHYR).OnlyIfRe('rw61x'), + TargetPart('freertos', os_env=NxpOsUsed.FREERTOS).ExceptIfRe('rw61x'), ]) # apps target.AppendFixedTargets([ TargetPart('lighting', app=NxpApp.LIGHTING).OnlyIfRe('(k32w0|k32w1)'), - TargetPart('contact-sensor', app=NxpApp.CONTACT).OnlyIfRe('(k32w0|k32w1)') + TargetPart('contact-sensor', app=NxpApp.CONTACT).OnlyIfRe('(k32w0|k32w1)'), + TargetPart('all-clusters', app=NxpApp.ALLCLUSTERS).OnlyIfRe('rw61x'), + TargetPart('laundry-washer', app=NxpApp.LAUNDRYWASHER).OnlyIfRe('rw61x'), + TargetPart('thermostat', app=NxpApp.THERMOSTAT).OnlyIfRe('rw61x') ]) target.AppendModifier(name="factory", enable_factory_data=True) @@ -513,8 +523,8 @@ def BuildNxpTarget(): target.AppendModifier(name="lit", enable_lit=True).OnlyIfRe('contact-sensor') target.AppendModifier(name="fro32k", use_fro32k=True).OnlyIfRe('k32w0') target.AppendModifier(name="smu2", smu2=True).OnlyIfRe('k32w1-lighting') - target.AppendModifier(name="dac-conversion", convert_dac_pk=True).OnlyIfRe('factory').ExceptIfRe('k32w0') - target.AppendModifier(name="rotating-id", enable_rotating_id=True) + target.AppendModifier(name="dac-conversion", convert_dac_pk=True).OnlyIfRe('factory').ExceptIfRe('(k32w0|rw61x)') + target.AppendModifier(name="rotating-id", enable_rotating_id=True).ExceptIfRe('rw61x') target.AppendModifier(name="sw-v2", has_sw_version_2=True) return target diff --git a/scripts/build/builders/nxp.py b/scripts/build/builders/nxp.py index 4bd4f0ae451875..74f40eaa0a36aa 100644 --- a/scripts/build/builders/nxp.py +++ b/scripts/build/builders/nxp.py @@ -1,4 +1,4 @@ -# 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. @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import logging import os from enum import Enum, auto @@ -19,15 +20,31 @@ from .gn import GnBuilder +class NxpOsUsed(Enum): + FREERTOS = auto() + ZEPHYR = auto() + + def OsEnv(self): + if self == NxpOsUsed.ZEPHYR: + return 'zephyr' + elif self == NxpOsUsed.FREERTOS: + return 'freertos' + else: + raise Exception('Unknown OS type: %r' % self) + + class NxpBoard(Enum): K32W0 = auto() K32W1 = auto() + RW61X = auto() def Name(self): if self == NxpBoard.K32W0: return 'k32w0x' elif self == NxpBoard.K32W1: return 'k32w1' + elif self == NxpBoard.RW61X: + return 'rd_rw612_bga' else: raise Exception('Unknown board type: %r' % self) @@ -36,6 +53,8 @@ def FolderName(self): return 'k32w/k32w0' elif self == NxpBoard.K32W1: return 'k32w/k32w1' + elif self == NxpBoard.RW61X: + return 'zephyr' else: raise Exception('Unknown board type: %r' % self) @@ -43,12 +62,21 @@ def FolderName(self): class NxpApp(Enum): LIGHTING = auto() CONTACT = auto() + ALLCLUSTERS = auto() + LAUNDRYWASHER = auto() + THERMOSTAT = auto() def ExampleName(self): if self == NxpApp.LIGHTING: return 'lighting-app' elif self == NxpApp.CONTACT: return "contact-sensor-app" + elif self == NxpApp.ALLCLUSTERS: + return "all-clusters-app" + elif self == NxpApp.LAUNDRYWASHER: + return "laundry-washer-app" + elif self == NxpApp.THERMOSTAT: + return "thermostat" else: raise Exception('Unknown app type: %r' % self) @@ -57,6 +85,12 @@ def NameSuffix(self): return 'light-example' elif self == NxpApp.CONTACT: return 'contact-example' + elif self == NxpApp.ALLCLUSTERS: + return "all-cluster-example" + elif self == NxpApp.LAUNDRYWASHER: + return "laundry-washer-example" + elif self == NxpApp.THERMOSTAT: + return "thermostat-example" else: raise Exception('Unknown app type: %r' % self) @@ -71,6 +105,7 @@ def __init__(self, runner, app: NxpApp = NxpApp.LIGHTING, board: NxpBoard = NxpBoard.K32W0, + os_env: NxpOsUsed = NxpOsUsed.FREERTOS, low_power: bool = False, smu2: bool = False, enable_factory_data: bool = False, @@ -85,6 +120,7 @@ def __init__(self, self.code_root = root self.app = app self.board = board + self.os_env = os_env self.low_power = low_power self.smu2 = smu2 self.enable_factory_data = enable_factory_data @@ -125,15 +161,54 @@ def GnBuildArgs(self): return args + def WestBuildArgs(self): + args = [] + if self.enable_factory_data: + args.append('-DFILE_SUFFIX=fdata') + + if self.has_sw_version_2: + args.append('-DCONFIG_CHIP_DEVICE_SOFTWARE_VERSION=2') + + build_args = " -- " + " ".join(args) if len(args) > 0 else "" + return build_args + def generate(self): - super(NxpBuilder, self).generate() + if self.os_env == NxpOsUsed.ZEPHYR: + if 'ZEPHYR_NXP_SDK_INSTALL_DIR' in os.environ: + cmd = 'export ZEPHYR_SDK_INSTALL_DIR="$ZEPHYR_NXP_SDK_INSTALL_DIR"\n' + else: + raise Exception("ZEPHYR_SDK_INSTALL_DIR need to be set") + if 'ZEPHYR_NXP_BASE' in os.environ: + cmd += 'export ZEPHYR_BASE="$ZEPHYR_NXP_BASE"\n' + else: + raise Exception("ZEPHYR_NXP_BASE need to be set") + build_args = self.WestBuildArgs() + cmd += ''' + west build -p --cmake-only -b {board_name} -d {out_folder} {example_folder} {build_args} + '''.format( + board_name=self.board.Name(), + out_folder=self.output_dir, + example_folder=self.app.BuildRoot(self.code_root, self.board), + build_args=build_args).strip() + self._Execute(['bash', '-c', cmd], title='Generating ' + self.identifier) + else: + super(NxpBuilder, self).generate() def build_outputs(self): name = 'chip-%s-%s' % (self.board.Name(), self.app.NameSuffix()) - yield BuilderOutput( - os.path.join(self.output_dir, name), - f'{name}.elf') - if self.options.enable_link_map_file: + if self.os_env == NxpOsUsed.ZEPHYR: + yield BuilderOutput( + os.path.join(self.output_dir, 'zephyr', 'zephyr.elf'), + f'{name}.elf') + if self.options.enable_link_map_file: + yield BuilderOutput( + os.path.join(self.output_dir, 'zephyr', 'zephyr.map'), + f'{name}.map') + else: yield BuilderOutput( - os.path.join(self.output_dir, f'{name}.map'), - f'{name}.map') + os.path.join(self.output_dir, name), + f'{name}.elf') + if self.options.enable_link_map_file: + yield BuilderOutput( + os.path.join(self.output_dir, f'{name}.map'), + f'{name}.map') diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index 7714bddaae42e3..2d9fee76e68ac0 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -14,7 +14,7 @@ linux-x64-efr32-test-runner[-clang] imx-{chip-tool,lighting-app,thermostat,all-clusters-app,all-clusters-minimal-app,ota-provider-app}[-release] infineon-psoc6-{lock,light,all-clusters,all-clusters-minimal}[-ota][-updateimage][-trustm] rw61x-{all-clusters-app,thermostat,laundry-washer}[-ota][-wifi][-thread][-factory-data][-matter-shell] -nxp-{k32w0,k32w1}-{lighting,contact-sensor}[-factory][-low-power][-lit][-fro32k][-smu2][-dac-conversion][-rotating-id][-sw-v2] +nxp-{k32w0,k32w1,rw61x}-{zephyr,freertos}-{lighting,contact-sensor,all-clusters,laundry-washer,thermostat}[-factory][-low-power][-lit][-fro32k][-smu2][-dac-conversion][-rotating-id][-sw-v2] mbed-cy8cproto_062_4343w-{lock,light,all-clusters,all-clusters-minimal,pigweed,ota-requestor,shell}[-release][-develop][-debug] mw320-all-clusters-app nrf-{nrf5340dk,nrf52840dk,nrf52840dongle}-{all-clusters,all-clusters-minimal,lock,light,light-switch,shell,pump,pump-controller,window-covering}[-rpc] diff --git a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/discovery_commands.py b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/discovery_commands.py index 17fa4f31e96a48..5cfcb6087cbddb 100644 --- a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/discovery_commands.py +++ b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/discovery_commands.py @@ -68,7 +68,8 @@ - + + diff --git a/scripts/rules.matterlint b/scripts/rules.matterlint index 335e37436be00c..eff738deb58d8e 100644 --- a/scripts/rules.matterlint +++ b/scripts/rules.matterlint @@ -19,6 +19,7 @@ load "../src/app/zap-templates/zcl/data-model/chip/chip-ota.xml"; load "../src/app/zap-templates/zcl/data-model/chip/chip-types.xml"; load "../src/app/zap-templates/zcl/data-model/chip/clusters-extensions.xml"; load "../src/app/zap-templates/zcl/data-model/chip/color-control-cluster.xml"; +load "../src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/concentration-measurement-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml"; @@ -100,6 +101,7 @@ load "../src/app/zap-templates/zcl/data-model/chip/unit-localization-cluster.xml load "../src/app/zap-templates/zcl/data-model/chip/user-label-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/wake-on-lan-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/washer-controls-cluster.xml"; +load "../src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/window-covering.xml"; diff --git a/scripts/setup/zap.json b/scripts/setup/zap.json index c3e65c8bab9752..636da03eeb2e8f 100644 --- a/scripts/setup/zap.json +++ b/scripts/setup/zap.json @@ -8,13 +8,13 @@ "mac-amd64", "windows-amd64" ], - "tags": ["version:2@v2024.06.10-nightly.1"] + "tags": ["version:2@v2024.07.10-nightly.1"] }, { "_comment": "Always get the amd64 version on mac until usable arm64 zap build is available", "path": "fuchsia/third_party/zap/mac-amd64", "platforms": ["mac-arm64"], - "tags": ["version:2@v2024.06.10-nightly.1"] + "tags": ["version:2@v2024.07.10-nightly.1"] } ] } diff --git a/scripts/setup/zap.version b/scripts/setup/zap.version index 8b3c20afc891f6..4414b06f961e8b 100644 --- a/scripts/setup/zap.version +++ b/scripts/setup/zap.version @@ -1 +1 @@ -v2024.06.10-nightly +v2024.07.10-nightly diff --git a/scripts/tests/chiptest/__init__.py b/scripts/tests/chiptest/__init__.py index d5a493b879d39b..a250bab52e9de4 100644 --- a/scripts/tests/chiptest/__init__.py +++ b/scripts/tests/chiptest/__init__.py @@ -188,6 +188,7 @@ def _GetDarwinFrameworkToolUnsupportedTests() -> Set[str]: "TestIcdManagementCluster", # darwin-framework-tool does not support ICD registration "TestUnitTestingClusterMei", # darwin-framework-tool does not currently support reading or subscribing to Events "TestReadNoneSubscribeNone", # darwin-framework-tool does not supports those commands. + "TestDiagnosticLogsDownloadCommand", # test is flaky in darwin. Please see #32636 "Test_TC_ACE_1_6", # darwin-framework-tool does not support group commands. "Test_TC_ACL_2_5", # darwin-framework-tool does not currently support reading or subscribing to Events diff --git a/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h b/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h index 8289394bce6d89..69486db49cfb77 100644 --- a/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h +++ b/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h @@ -261,7 +261,7 @@ #define GENERATED_DEFAULTS_COUNT (30) // This is an array of EmberAfAttributeMinMaxValue structures. -#define GENERATED_MIN_MAX_DEFAULT_COUNT 48 +#define GENERATED_MIN_MAX_DEFAULT_COUNT 49 #define GENERATED_MIN_MAX_DEFAULTS \ { \ \ @@ -289,6 +289,9 @@ /* Endpoint: 1, Cluster: Valve Configuration and Control (server) */ \ { (uint16_t) 0x64, (uint16_t) 0x1, (uint16_t) 0x64 }, /* DefaultOpenLevel */ \ \ + /* Endpoint: 1, Cluster: Energy EVSE (server) */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFFFE }, /* ApproximateEVEfficiency */ \ + \ /* Endpoint: 1, Cluster: Window Covering (server) */ \ { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xF }, /* Mode */ \ \ @@ -1235,8 +1238,8 @@ ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* NextChargeRequiredEnergy */ \ { ZAP_EMPTY_DEFAULT(), 0x00000026, 1, ZAP_TYPE(PERCENT), \ ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* NextChargeTargetSoC */ \ - { ZAP_EMPTY_DEFAULT(), 0x00000027, 2, ZAP_TYPE(INT16U), \ - ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(WRITABLE) | \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(8), 0x00000027, 2, ZAP_TYPE(INT16U), \ + ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(WRITABLE) | \ ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* ApproximateEVEfficiency */ \ { ZAP_EMPTY_DEFAULT(), 0x00000040, 4, ZAP_TYPE(INT32U), \ ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* SessionID */ \ @@ -1312,7 +1315,7 @@ ZAP_ATTRIBUTE_MASK(TOKENIZE) }, /* InstalledOpenLimitTilt */ \ { ZAP_SIMPLE_DEFAULT(0xFFFF), 0x00000013, 2, ZAP_TYPE(INT16U), \ ZAP_ATTRIBUTE_MASK(TOKENIZE) }, /* InstalledClosedLimitTilt */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(8), 0x00000017, 1, ZAP_TYPE(BITMAP8), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(9), 0x00000017, 1, ZAP_TYPE(BITMAP8), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* Mode */ \ { ZAP_SIMPLE_DEFAULT(0x00), 0x0000001A, 2, ZAP_TYPE(BITMAP16), 0 }, /* SafetyStatus */ \ { ZAP_SIMPLE_DEFAULT(0x17), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), 0 }, /* FeatureMap */ \ @@ -1350,9 +1353,9 @@ { ZAP_EMPTY_DEFAULT(), 0x00000016, 3, ZAP_TYPE(INT24U), ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* Power */ \ { ZAP_SIMPLE_DEFAULT(0x00000000), 0x00000017, 4, ZAP_TYPE(INT32U), \ ZAP_ATTRIBUTE_MASK(WRITABLE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* LifetimeEnergyConsumed */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(9), 0x00000020, 1, ZAP_TYPE(ENUM8), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(10), 0x00000020, 1, ZAP_TYPE(ENUM8), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* OperationMode */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(10), 0x00000021, 1, ZAP_TYPE(ENUM8), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(11), 0x00000021, 1, ZAP_TYPE(ENUM8), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* ControlMode */ \ { ZAP_SIMPLE_DEFAULT(0x1F), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), 0 }, /* FeatureMap */ \ { ZAP_SIMPLE_DEFAULT(4), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \ @@ -1363,23 +1366,23 @@ { ZAP_SIMPLE_DEFAULT(0x0BB8), 0x00000004, 2, ZAP_TYPE(TEMPERATURE), 0 }, /* AbsMaxHeatSetpointLimit */ \ { ZAP_SIMPLE_DEFAULT(0x0640), 0x00000005, 2, ZAP_TYPE(TEMPERATURE), 0 }, /* AbsMinCoolSetpointLimit */ \ { ZAP_SIMPLE_DEFAULT(0x0C80), 0x00000006, 2, ZAP_TYPE(TEMPERATURE), 0 }, /* AbsMaxCoolSetpointLimit */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(11), 0x00000011, 2, ZAP_TYPE(INT16S), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(12), 0x00000011, 2, ZAP_TYPE(INT16S), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* OccupiedCoolingSetpoint */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(12), 0x00000012, 2, ZAP_TYPE(INT16S), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(13), 0x00000012, 2, ZAP_TYPE(INT16S), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* OccupiedHeatingSetpoint */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(13), 0x00000015, 2, ZAP_TYPE(INT16S), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(14), 0x00000015, 2, ZAP_TYPE(INT16S), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* MinHeatSetpointLimit */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(14), 0x00000016, 2, ZAP_TYPE(INT16S), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(15), 0x00000016, 2, ZAP_TYPE(INT16S), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* MaxHeatSetpointLimit */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(15), 0x00000017, 2, ZAP_TYPE(INT16S), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(16), 0x00000017, 2, ZAP_TYPE(INT16S), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* MinCoolSetpointLimit */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(16), 0x00000018, 2, ZAP_TYPE(INT16S), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(17), 0x00000018, 2, ZAP_TYPE(INT16S), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* MaxCoolSetpointLimit */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(17), 0x00000019, 1, ZAP_TYPE(INT8S), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(18), 0x00000019, 1, ZAP_TYPE(INT8S), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* MinSetpointDeadBand */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(18), 0x0000001B, 1, ZAP_TYPE(ENUM8), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(19), 0x0000001B, 1, ZAP_TYPE(ENUM8), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* ControlSequenceOfOperation */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(19), 0x0000001C, 1, ZAP_TYPE(ENUM8), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(20), 0x0000001C, 1, ZAP_TYPE(ENUM8), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* SystemMode */ \ { ZAP_EMPTY_DEFAULT(), 0x00000048, 0, ZAP_TYPE(ARRAY), ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) }, /* PresetTypes */ \ { ZAP_EMPTY_DEFAULT(), 0x00000049, 0, ZAP_TYPE(ARRAY), ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) }, /* ScheduleTypes */ \ @@ -1405,14 +1408,14 @@ { ZAP_SIMPLE_DEFAULT(6), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Fan Control (server) */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(20), 0x00000000, 1, ZAP_TYPE(ENUM8), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(21), 0x00000000, 1, ZAP_TYPE(ENUM8), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* FanMode */ \ { ZAP_SIMPLE_DEFAULT(0x02), 0x00000001, 1, ZAP_TYPE(ENUM8), 0 }, /* FanModeSequence */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(21), 0x00000002, 1, ZAP_TYPE(PERCENT), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(22), 0x00000002, 1, ZAP_TYPE(PERCENT), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* PercentSetting */ \ { ZAP_SIMPLE_DEFAULT(0x00), 0x00000003, 1, ZAP_TYPE(PERCENT), 0 }, /* PercentCurrent */ \ { ZAP_SIMPLE_DEFAULT(100), 0x00000004, 1, ZAP_TYPE(INT8U), 0 }, /* SpeedMax */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(22), 0x00000005, 1, ZAP_TYPE(INT8U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(23), 0x00000005, 1, ZAP_TYPE(INT8U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* SpeedSetting */ \ { ZAP_SIMPLE_DEFAULT(0x00), 0x00000006, 1, ZAP_TYPE(INT8U), 0 }, /* SpeedCurrent */ \ { ZAP_SIMPLE_DEFAULT(0x03), 0x00000007, 1, ZAP_TYPE(BITMAP8), 0 }, /* RockSupport */ \ @@ -1424,11 +1427,11 @@ { ZAP_SIMPLE_DEFAULT(4), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Thermostat User Interface Configuration (server) */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(23), 0x00000000, 1, ZAP_TYPE(ENUM8), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(24), 0x00000000, 1, ZAP_TYPE(ENUM8), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* TemperatureDisplayMode */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(24), 0x00000001, 1, ZAP_TYPE(ENUM8), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(25), 0x00000001, 1, ZAP_TYPE(ENUM8), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* KeypadLockout */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(25), 0x00000002, 1, ZAP_TYPE(ENUM8), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(26), 0x00000002, 1, ZAP_TYPE(ENUM8), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* ScheduleProgrammingVisibility */ \ { ZAP_SIMPLE_DEFAULT(0), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), 0 }, /* FeatureMap */ \ { ZAP_SIMPLE_DEFAULT(2), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \ @@ -1464,25 +1467,25 @@ { ZAP_EMPTY_DEFAULT(), 0x00000028, 2, ZAP_TYPE(INT16U), 0 }, /* Primary6X */ \ { ZAP_EMPTY_DEFAULT(), 0x00000029, 2, ZAP_TYPE(INT16U), 0 }, /* Primary6Y */ \ { ZAP_EMPTY_DEFAULT(), 0x0000002A, 1, ZAP_TYPE(INT8U), ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* Primary6Intensity */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(26), 0x00000030, 2, ZAP_TYPE(INT16U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(27), 0x00000030, 2, ZAP_TYPE(INT16U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* WhitePointX */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(27), 0x00000031, 2, ZAP_TYPE(INT16U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(28), 0x00000031, 2, ZAP_TYPE(INT16U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* WhitePointY */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(28), 0x00000032, 2, ZAP_TYPE(INT16U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(29), 0x00000032, 2, ZAP_TYPE(INT16U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* ColorPointRX */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(29), 0x00000033, 2, ZAP_TYPE(INT16U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(30), 0x00000033, 2, ZAP_TYPE(INT16U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* ColorPointRY */ \ { ZAP_EMPTY_DEFAULT(), 0x00000034, 1, ZAP_TYPE(INT8U), \ ZAP_ATTRIBUTE_MASK(WRITABLE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* ColorPointRIntensity */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(30), 0x00000036, 2, ZAP_TYPE(INT16U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(31), 0x00000036, 2, ZAP_TYPE(INT16U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* ColorPointGX */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(31), 0x00000037, 2, ZAP_TYPE(INT16U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(32), 0x00000037, 2, ZAP_TYPE(INT16U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* ColorPointGY */ \ { ZAP_EMPTY_DEFAULT(), 0x00000038, 1, ZAP_TYPE(INT8U), \ ZAP_ATTRIBUTE_MASK(WRITABLE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* ColorPointGIntensity */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(32), 0x0000003A, 2, ZAP_TYPE(INT16U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(33), 0x0000003A, 2, ZAP_TYPE(INT16U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* ColorPointBX */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(33), 0x0000003B, 2, ZAP_TYPE(INT16U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(34), 0x0000003B, 2, ZAP_TYPE(INT16U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* ColorPointBY */ \ { ZAP_EMPTY_DEFAULT(), 0x0000003C, 1, ZAP_TYPE(INT8U), \ ZAP_ATTRIBUTE_MASK(WRITABLE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* ColorPointBIntensity */ \ @@ -1498,7 +1501,7 @@ { ZAP_SIMPLE_DEFAULT(0x0000), 0x0000400B, 2, ZAP_TYPE(INT16U), 0 }, /* ColorTempPhysicalMinMireds */ \ { ZAP_SIMPLE_DEFAULT(0xFEFF), 0x0000400C, 2, ZAP_TYPE(INT16U), 0 }, /* ColorTempPhysicalMaxMireds */ \ { ZAP_EMPTY_DEFAULT(), 0x0000400D, 2, ZAP_TYPE(INT16U), 0 }, /* CoupleColorTempToLevelMinMireds */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(34), 0x00004010, 2, ZAP_TYPE(INT16U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(35), 0x00004010, 2, ZAP_TYPE(INT16U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(WRITABLE) | \ ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* StartUpColorTemperatureMireds */ \ { ZAP_SIMPLE_DEFAULT(0x1F), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), 0 }, /* FeatureMap */ \ @@ -1508,13 +1511,13 @@ { ZAP_SIMPLE_DEFAULT(0x01), 0x00000000, 1, ZAP_TYPE(INT8U), 0 }, /* PhysicalMinLevel */ \ { ZAP_SIMPLE_DEFAULT(0xFE), 0x00000001, 1, ZAP_TYPE(INT8U), 0 }, /* PhysicalMaxLevel */ \ { ZAP_SIMPLE_DEFAULT(0x00), 0x00000002, 1, ZAP_TYPE(BITMAP8), 0 }, /* BallastStatus */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(35), 0x00000010, 1, ZAP_TYPE(INT8U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(36), 0x00000010, 1, ZAP_TYPE(INT8U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* MinLevel */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(36), 0x00000011, 1, ZAP_TYPE(INT8U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(37), 0x00000011, 1, ZAP_TYPE(INT8U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* MaxLevel */ \ { ZAP_EMPTY_DEFAULT(), 0x00000014, 1, ZAP_TYPE(INT8U), \ ZAP_ATTRIBUTE_MASK(WRITABLE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* IntrinsicBallastFactor */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(37), 0x00000015, 1, ZAP_TYPE(INT8U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(38), 0x00000015, 1, ZAP_TYPE(INT8U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) | \ ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* BallastFactorAdjustment */ \ { ZAP_EMPTY_DEFAULT(), 0x00000020, 1, ZAP_TYPE(INT8U), 0 }, /* LampQuantity */ \ @@ -1524,7 +1527,7 @@ ZAP_ATTRIBUTE_MASK(WRITABLE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* LampRatedHours */ \ { ZAP_SIMPLE_DEFAULT(0x000000), 0x00000033, 3, ZAP_TYPE(INT24U), \ ZAP_ATTRIBUTE_MASK(WRITABLE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* LampBurnHours */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(38), 0x00000034, 1, ZAP_TYPE(BITMAP8), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(39), 0x00000034, 1, ZAP_TYPE(BITMAP8), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* LampAlarmMode */ \ { ZAP_SIMPLE_DEFAULT(0xFFFFFF), 0x00000035, 3, ZAP_TYPE(INT24U), \ ZAP_ATTRIBUTE_MASK(WRITABLE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* LampBurnHoursTripPoint */ \ @@ -1871,13 +1874,13 @@ { ZAP_EMPTY_DEFAULT(), 0x00000024, 1, ZAP_TYPE(ENUM8), ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* enum_attr */ \ { ZAP_EMPTY_DEFAULT(), 0x00000025, 0, ZAP_TYPE(STRUCT), \ ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* struct_attr */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(39), 0x00000026, 1, ZAP_TYPE(INT8U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(40), 0x00000026, 1, ZAP_TYPE(INT8U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* range_restricted_int8u */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(40), 0x00000027, 1, ZAP_TYPE(INT8S), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(41), 0x00000027, 1, ZAP_TYPE(INT8S), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* range_restricted_int8s */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(41), 0x00000028, 2, ZAP_TYPE(INT16U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(42), 0x00000028, 2, ZAP_TYPE(INT16U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* range_restricted_int16u */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(42), 0x00000029, 2, ZAP_TYPE(INT16S), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(43), 0x00000029, 2, ZAP_TYPE(INT16S), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* range_restricted_int16s */ \ { ZAP_EMPTY_DEFAULT(), 0x0000002A, 0, ZAP_TYPE(ARRAY), \ ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* list_long_octet_string */ \ @@ -1948,16 +1951,16 @@ { ZAP_EMPTY_DEFAULT(), 0x00004025, 0, ZAP_TYPE(STRUCT), \ ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(WRITABLE) | \ ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* nullable_struct */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(43), 0x00004026, 1, ZAP_TYPE(INT8U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(44), 0x00004026, 1, ZAP_TYPE(INT8U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) | \ ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* nullable_range_restricted_int8u */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(44), 0x00004027, 1, ZAP_TYPE(INT8S), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(45), 0x00004027, 1, ZAP_TYPE(INT8S), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) | \ ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* nullable_range_restricted_int8s */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(45), 0x00004028, 2, ZAP_TYPE(INT16U), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(46), 0x00004028, 2, ZAP_TYPE(INT16U), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) | \ ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* nullable_range_restricted_int16u */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(46), 0x00004029, 2, ZAP_TYPE(INT16S), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(47), 0x00004029, 2, ZAP_TYPE(INT16S), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) | \ ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* nullable_range_restricted_int16s */ \ { ZAP_EMPTY_DEFAULT(), 0x0000402A, 1, ZAP_TYPE(INT8U), \ @@ -1982,7 +1985,7 @@ { ZAP_SIMPLE_DEFAULT(1), 0x00004000, 1, ZAP_TYPE(BOOLEAN), 0 }, /* GlobalSceneControl */ \ { ZAP_SIMPLE_DEFAULT(0), 0x00004001, 2, ZAP_TYPE(INT16U), ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* OnTime */ \ { ZAP_SIMPLE_DEFAULT(0), 0x00004002, 2, ZAP_TYPE(INT16U), ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* OffWaitTime */ \ - { ZAP_MIN_MAX_DEFAULTS_INDEX(47), 0x00004003, 1, ZAP_TYPE(ENUM8), \ + { ZAP_MIN_MAX_DEFAULTS_INDEX(48), 0x00004003, 1, ZAP_TYPE(ENUM8), \ ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* StartUpOnOff */ \ { ZAP_SIMPLE_DEFAULT(0x0001), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), 0 }, /* FeatureMap */ \ { ZAP_SIMPLE_DEFAULT(6), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \ diff --git a/scripts/tools/zap/zap_execution.py b/scripts/tools/zap/zap_execution.py index 80def9602dce77..d027079ac70070 100644 --- a/scripts/tools/zap/zap_execution.py +++ b/scripts/tools/zap/zap_execution.py @@ -23,7 +23,7 @@ # Use scripts/tools/zap/version_update.py to manage ZAP versioning as many # files may need updating for versions # -MIN_ZAP_VERSION = '2024.6.6' +MIN_ZAP_VERSION = '2024.7.10' class ZapTool: diff --git a/scripts/tools/zap_regen_all.py b/scripts/tools/zap_regen_all.py index dce4f719a19829..afe931fd8609a6 100755 --- a/scripts/tools/zap_regen_all.py +++ b/scripts/tools/zap_regen_all.py @@ -350,7 +350,8 @@ def setupArgumentsParser(): parser.add_argument('--parallel', action='store_true') parser.add_argument('--no-parallel', action='store_false', dest='parallel') - parser.set_defaults(parallel=True) + parser.add_argument('--no-rerun-in-env', action='store_false', dest='rerun_in_env') + parser.set_defaults(parallel=True, rerun_in_env=True) args = parser.parse_args() @@ -495,6 +496,26 @@ def main(): level=logging.INFO, format='%(asctime)s %(name)s %(levelname)-7s %(message)s' ) + + # The scripts executed by this generally MUST be within a bootstrapped environment because + # we need: + # - zap-cli in PATH + # - scripts/codegen.py uses click (can be in current pyenv, but guaranteed in bootstrap) + # - formatting is using bootstrapped clang-format + # Figure out if bootstrapped. For now assume `PW_ROOT` is such a marker in the environment + if "PW_ROOT" not in os.environ: + logging.error("Script MUST be run in a bootstrapped environment.") + + # using the `--no-rerun-in-env` to avoid recursive infinite calls + if '--no-rerun-in-env' not in sys.argv: + import shlex + logging.info("Will re-try running in a build environment....") + + what_to_run = sys.argv + ['--no-rerun-in-env'] + launcher = os.path.join(CHIP_ROOT_DIR, 'scripts', 'run_in_build_env.sh') + os.execv(launcher, [launcher, shlex.join(what_to_run)]) + sys.exit(1) + checkPythonVersion() os.chdir(CHIP_ROOT_DIR) args = setupArgumentsParser() diff --git a/src/BUILD.gn b/src/BUILD.gn index 3f4421d2f3f584..7e5fedcc0d539b 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -51,6 +51,7 @@ if (chip_build_tests) { deps = [] tests = [ "${chip_root}/src/app/data-model/tests", + "${chip_root}/src/app/cluster-building-blocks/tests", "${chip_root}/src/app/data-model-interface/tests", "${chip_root}/src/access/tests", "${chip_root}/src/crypto/tests", diff --git a/src/app/AttributeAccessInterfaceCache.h b/src/app/AttributeAccessInterfaceCache.h index 21e29410f9a367..9268a7096ea9d5 100644 --- a/src/app/AttributeAccessInterfaceCache.h +++ b/src/app/AttributeAccessInterfaceCache.h @@ -48,7 +48,7 @@ class AttributeAccessInterfaceCache kDefinitelyUsed }; - constexpr AttributeAccessInterfaceCache() = default; + AttributeAccessInterfaceCache() { Invalidate(); } /** * @brief Invalidate the whole cache. Must be called every time list of AAI registrations changes. @@ -106,8 +106,6 @@ class AttributeAccessInterfaceCache private: struct AttributeAccessCacheEntry { - constexpr AttributeAccessCacheEntry() = default; - EndpointId endpointId = kInvalidEndpointId; ClusterId clusterId = kInvalidClusterId; AttributeAccessInterface * accessor = nullptr; @@ -139,8 +137,8 @@ class AttributeAccessInterfaceCache return &mCacheSlots[0]; } - AttributeAccessCacheEntry mCacheSlots[1] = {}; - AttributeAccessCacheEntry mLastUnusedEntry{}; + AttributeAccessCacheEntry mCacheSlots[1]; + AttributeAccessCacheEntry mLastUnusedEntry; }; } // namespace app diff --git a/src/app/BUILD.gn b/src/app/BUILD.gn index 55bc5f305ddd99..666c452b09dc3a 100644 --- a/src/app/BUILD.gn +++ b/src/app/BUILD.gn @@ -207,7 +207,7 @@ static_library("interaction-model") { public_deps = [ ":app_config", - ":command-handler", + ":command-handler-impl", ":constants", ":paths", ":subscription-info-provider", @@ -333,16 +333,32 @@ source_set("status-response") { ] } -source_set("command-handler") { +source_set("command-handler-interface") { sources = [ "CommandHandler.cpp", "CommandHandler.h", "CommandHandlerExchangeInterface.h", + ] + + public_deps = [ + ":paths", + "${chip_root}/src/access:types", + "${chip_root}/src/app/data-model", + "${chip_root}/src/lib/core", + "${chip_root}/src/lib/support", + "${chip_root}/src/messaging", + "${chip_root}/src/protocols/interaction_model", + ] +} + +source_set("command-handler-impl") { + sources = [ "CommandHandlerImpl.cpp", "CommandHandlerImpl.h", ] public_deps = [ + ":command-handler-interface", ":paths", ":required-privileges", ":status-response", diff --git a/src/app/CommandHandlerImpl.cpp b/src/app/CommandHandlerImpl.cpp index 8c2572db590c17..b1843d23e8b0cd 100644 --- a/src/app/CommandHandlerImpl.cpp +++ b/src/app/CommandHandlerImpl.cpp @@ -323,6 +323,7 @@ void CommandHandlerImpl::InvalidateHandles() { handle->Invalidate(); } + mpHandleList.Clear(); } void CommandHandlerImpl::IncrementHoldOff(Handle * apHandle) diff --git a/src/app/EventLoggingTypes.h b/src/app/EventLoggingTypes.h index 666cb3886331fe..04a843ebcfbd60 100644 --- a/src/app/EventLoggingTypes.h +++ b/src/app/EventLoggingTypes.h @@ -100,7 +100,7 @@ struct Timestamp kSystem = 0, kEpoch }; - constexpr Timestamp() = default; + Timestamp() {} Timestamp(Type aType, uint64_t aValue) : mType(aType), mValue(aValue) {} Timestamp(System::Clock::Timestamp aValue) : mType(Type::kSystem), mValue(aValue.count()) {} static Timestamp Epoch(System::Clock::Timestamp aValue) diff --git a/src/app/EventManagement.cpp b/src/app/EventManagement.cpp index 7b210064898b6e..8e6d53c24c9636 100644 --- a/src/app/EventManagement.cpp +++ b/src/app/EventManagement.cpp @@ -32,7 +32,7 @@ using namespace chip::TLV; namespace chip { namespace app { -EventManagement EventManagement::sInstance; +static EventManagement sInstance; /** * @brief diff --git a/src/app/EventManagement.h b/src/app/EventManagement.h index 16e2271d3448b5..ce5a34039ea0fe 100644 --- a/src/app/EventManagement.h +++ b/src/app/EventManagement.h @@ -73,7 +73,7 @@ namespace app { inline constexpr const uint32_t kEventManagementProfile = 0x1; inline constexpr const uint32_t kFabricIndexTag = 0x1; inline constexpr size_t kMaxEventSizeReserve = 512; -inline constexpr uint16_t kRequiredEventField = +constexpr uint16_t kRequiredEventField = (1 << to_underlying(EventDataIB::Tag::kPriority)) | (1 << to_underlying(EventDataIB::Tag::kPath)); /** @@ -388,9 +388,6 @@ class EventManagement void SetScheduledEventInfo(EventNumber & aEventNumber, uint32_t & aInitialWrittenEventBytes) const; private: - constexpr EventManagement() = default; - static EventManagement sInstance; - /** * @brief * Internal structure for traversing events. @@ -558,9 +555,9 @@ class EventManagement MonotonicallyIncreasingCounter * mpEventNumberCounter = nullptr; EventNumber mLastEventNumber = 0; ///< Last event Number vended - Timestamp mLastEventTimestamp{}; ///< The timestamp of the last event in this buffer + Timestamp mLastEventTimestamp; ///< The timestamp of the last event in this buffer - System::Clock::Milliseconds64 mMonotonicStartupTime{}; + System::Clock::Milliseconds64 mMonotonicStartupTime; }; } // namespace app } // namespace chip diff --git a/src/app/OperationalSessionSetup.cpp b/src/app/OperationalSessionSetup.cpp index 5b2f00ed0a3798..156003dec8ffd5 100644 --- a/src/app/OperationalSessionSetup.cpp +++ b/src/app/OperationalSessionSetup.cpp @@ -197,8 +197,10 @@ void OperationalSessionSetup::Connect(Callback::Callback * on Connect(onConnection, nullptr, onSetupFailure, transportPayloadCapability); } -void OperationalSessionSetup::UpdateDeviceData(const Transport::PeerAddress & addr, const ReliableMessageProtocolConfig & config) +void OperationalSessionSetup::UpdateDeviceData(const ResolveResult & result) { + auto & config = result.mrpRemoteConfig; + auto addr = result.address; #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES // Make sure to clear out our reason for trying the next result first thing, // so it does not stick around in various error cases. @@ -248,7 +250,7 @@ void OperationalSessionSetup::UpdateDeviceData(const Transport::PeerAddress & ad return; } - CHIP_ERROR err = EstablishConnection(config); + CHIP_ERROR err = EstablishConnection(result); LogErrorOnFailure(err); if (err == CHIP_NO_ERROR) { @@ -292,15 +294,26 @@ void OperationalSessionSetup::UpdateDeviceData(const Transport::PeerAddress & ad // Do not touch `this` instance anymore; it has been destroyed in DequeueConnectionCallbacks. } -CHIP_ERROR OperationalSessionSetup::EstablishConnection(const ReliableMessageProtocolConfig & config) +CHIP_ERROR OperationalSessionSetup::EstablishConnection(const ResolveResult & result) { + auto & config = result.mrpRemoteConfig; #if INET_CONFIG_ENABLE_TCP_ENDPOINT - // TODO: Combine LargePayload flag with DNS-SD advertisements from peer. - // Issue #32348. if (mTransportPayloadCapability == TransportPayloadCapability::kLargePayload) { - // Set the transport type for carrying large payloads - mDeviceAddress.SetTransportType(chip::Transport::Type::kTcp); + if (result.supportsTcpServer) + { + // Set the transport type for carrying large payloads + mDeviceAddress.SetTransportType(chip::Transport::Type::kTcp); + } + else + { + // we should not set the large payload while the TCP support is not enabled + ChipLogError( + Discovery, + "LargePayload session requested but peer does not support TCP server, PeerNodeId=" ChipLogFormatScopedNodeId, + ChipLogValueScopedNodeId(mPeerId)); + return CHIP_ERROR_INTERNAL; + } } #endif @@ -627,7 +640,7 @@ void OperationalSessionSetup::PerformAddressUpdate() void OperationalSessionSetup::OnNodeAddressResolved(const PeerId & peerId, const ResolveResult & result) { - UpdateDeviceData(result.address, result.mrpRemoteConfig); + UpdateDeviceData(result); } void OperationalSessionSetup::OnNodeAddressResolutionFailed(const PeerId & peerId, CHIP_ERROR reason) diff --git a/src/app/OperationalSessionSetup.h b/src/app/OperationalSessionSetup.h index 508c778923fd49..343ce77b2ba37f 100644 --- a/src/app/OperationalSessionSetup.h +++ b/src/app/OperationalSessionSetup.h @@ -347,7 +347,7 @@ class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, void MoveToState(State aTargetState); - CHIP_ERROR EstablishConnection(const ReliableMessageProtocolConfig & config); + CHIP_ERROR EstablishConnection(const AddressResolve::ResolveResult & result); /* * This checks to see if an existing CASE session exists to the peer within the SessionManager @@ -419,7 +419,7 @@ class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, /** * This function will set new IP address, port and MRP retransmission intervals of the device. */ - void UpdateDeviceData(const Transport::PeerAddress & addr, const ReliableMessageProtocolConfig & config); + void UpdateDeviceData(const AddressResolve::ResolveResult & result); #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES /** diff --git a/src/app/WriteClient.h b/src/app/WriteClient.h index b67bf4ea0b8c84..b4d803981be3d8 100644 --- a/src/app/WriteClient.h +++ b/src/app/WriteClient.h @@ -178,7 +178,7 @@ class WriteClient : public Messaging::ExchangeDelegate ReturnErrorOnFailure(EncodeSingleAttributeDataIB(path, DataModel::List())); path.mListOp = ConcreteDataAttributePath::ListOperation::AppendItem; - for (ListIndex i = 0; i < value.size(); i++) + for (size_t i = 0; i < value.size(); i++) { ReturnErrorOnFailure(EncodeSingleAttributeDataIB(path, value.data()[i])); } diff --git a/src/app/app-platform/ContentAppPlatform.cpp b/src/app/app-platform/ContentAppPlatform.cpp index fb2d6ab39a1b5f..214af261e26e54 100644 --- a/src/app/app-platform/ContentAppPlatform.cpp +++ b/src/app/app-platform/ContentAppPlatform.cpp @@ -387,6 +387,57 @@ ContentApp * ContentAppPlatform::GetContentApp(EndpointId id) return nullptr; } +// create a string key from vendorId and productId +std::string createKey(uint16_t vendorId, uint16_t productId) +{ + return std::to_string(vendorId) + ":" + std::to_string(productId); +} + +void ContentAppPlatform::StoreNodeIdForContentApp(uint16_t vendorId, uint16_t productId, NodeId nodeId) +{ + std::string key = createKey(vendorId, productId); + + ChipLogProgress(DeviceLayer, "Stored node id: " ChipLogFormatX64 " for key: %s", ChipLogValueX64(nodeId), key.c_str()); + + mConnectedContentAppNodeIds[key].insert(nodeId); +} + +std::set ContentAppPlatform::GetNodeIdsForContentApp(uint16_t vendorId, uint16_t productId) +{ + std::string key = createKey(vendorId, productId); + + ChipLogProgress(DeviceLayer, "Retrieving node id for key: %s", key.c_str()); + + auto it = mConnectedContentAppNodeIds.find(key); + if (it != mConnectedContentAppNodeIds.end()) + { + ChipLogProgress(DeviceLayer, "Found node id"); + return it->second; + } + + ChipLogProgress(DeviceLayer, "Didn't find node id"); + // If key not found, return an empty set + return {}; +} + +std::set ContentAppPlatform::GetNodeIdsForAllowVendorId(uint16_t vendorId) +{ + std::set result; + std::string vendorPrefix = std::to_string(vendorId) + ":"; + + for (const auto & pair : mConnectedContentAppNodeIds) + { + const std::string & key = pair.first; + if (key.find(vendorPrefix) == 0) + { // Check if the key starts with the vendor prefix + const std::set & nodeIds = pair.second; + result.insert(nodeIds.begin(), nodeIds.end()); + } + } + + return result; +} + void ContentAppPlatform::SetCurrentApp(ContentApp * app) { if (!HasCurrentApp()) diff --git a/src/app/app-platform/ContentAppPlatform.h b/src/app/app-platform/ContentAppPlatform.h index 16a47c26a3b991..45615d09ed8ddf 100644 --- a/src/app/app-platform/ContentAppPlatform.h +++ b/src/app/app-platform/ContentAppPlatform.h @@ -161,6 +161,18 @@ class DLL_EXPORT ContentAppPlatform bool HasTargetContentApp(uint16_t vendorId, uint16_t productId, CharSpan rotatingId, Protocols::UserDirectedCommissioning::TargetAppInfo & info, uint32_t & passcode); + // returns set of connected nodes for a given content app + std::set GetNodeIdsForContentApp(uint16_t vendorId, uint16_t productId); + + // returns set of connected nodes for a given allowed vendor id + std::set GetNodeIdsForAllowVendorId(uint16_t vendorId); + + // store node id for content app after commissioning + // node id can be used later on to update ACL + // in case app is not installed + // Note: This is in memory storing, the values are deleted after reboot + void StoreNodeIdForContentApp(uint16_t vendorId, uint16_t productId, NodeId nodeId); + /** * @brief * Add ACLs on this device for the given client, @@ -201,6 +213,8 @@ class DLL_EXPORT ContentAppPlatform EndpointId mCurrentEndpointId; EndpointId mFirstDynamicEndpointId; ContentApp * mContentApps[CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT]; + // key is string -> vendorId:producTid + std::map> mConnectedContentAppNodeIds; private: void IncrementCurrentEndpointID(); diff --git a/src/app/cluster-building-blocks/BUILD.gn b/src/app/cluster-building-blocks/BUILD.gn new file mode 100644 index 00000000000000..dedce36ea43e6b --- /dev/null +++ b/src/app/cluster-building-blocks/BUILD.gn @@ -0,0 +1,24 @@ +# 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/chip.gni") + +source_set("cluster-building-blocks") { + sources = [ "QuieterReporting.h" ] + + public_deps = [ + "${chip_root}/src/app/data-model:nullable", + "${chip_root}/src/lib/support:support", + "${chip_root}/src/system", + ] +} diff --git a/src/app/cluster-building-blocks/QuieterReporting.h b/src/app/cluster-building-blocks/QuieterReporting.h new file mode 100644 index 00000000000000..d973f57c1a11ae --- /dev/null +++ b/src/app/cluster-building-blocks/QuieterReporting.h @@ -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. + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include + +namespace chip { +namespace app { + +enum class QuieterReportingPolicyEnum +{ + kMarkDirtyOnChangeToFromZero = (1u << 0), + kMarkDirtyOnDecrement = (1u << 1), + kMarkDirtyOnIncrement = (1u << 2), +}; + +enum class AttributeDirtyState +{ + kNoReportNeeded = 0, + kMustReport = 1, +}; + +using QuieterReportingPolicyFlags = BitFlags; + +namespace detail { + +using Timestamp = System::Clock::Milliseconds64; +template +using Nullable = DataModel::Nullable; + +/** + * This class helps track reporting state of an attribute to properly keep track of whether + * it needs to be marked as dirty or not for purposes of reporting using + * "7.7.9 Quieter Reporting Quality" (Q quality) + * + * The class can be configured via `policy()` to have some/all of the common reasons + * for reporting (e.g. increment only, decrement only, change to/from zero). + * + * Changes of null to non-null or non-null to null are always considered dirty. + * + * It is possible to force mark the attribute as dirty (see `ForceDirty()`) such as + * for conditions like "When there is any increase or decrease in the estimated time + * remaining that was due to progressing insight of the server's control logic". + * + * Class maintains a `current value` and a timestamped `dirty` state. The `SetValue()` + * method must be used to update the `current value` and will return AttributeDirtyState::kMustReport + * if the attribute should be marked dirty/ + * + * - `SetValue()` has internal rules for null/non-null changes and policy-based rules + * - `SetValue()` with a `SufficientChangePredicate` uses the internal rules in addition to + * the predicate to determine dirty state + * + * See [QuieterReportingPolicyEnum] for policy flags on when a value is considered dirty + * beyond non/non-null changes. + * + * Common quieter reporting usecases that can be supported by this class are: + * - If attribute has changed due to a change in the X or Y attributes + * - Use SufficientChangePredicate version + * - When it changes from 0 to any other value and vice versa + * - Use `kMarkDirtyOnChangeToFromZero` internal policy. + * - When it changes from null to any other value and vice versa + * - Built-in rule. + * - When it increases + * - Use `kMarkDirtyOnIncrement` internal policy. + * - When it decreases + * - Use `kMarkDirtyOnDecrement` internal policy. + * - When there is any increase or decrease in the estimated time remaining that was + * due to progressing insight of the server's control logic + * - Use SufficientChangePredicate version with an always-true predicate. + * - When it changes at a rate significantly different from one unit per second. + * - Use SufficientChangePredicate version. + * Example usage in-situ: + * + * Class has: + * QuieterReportingAttribute mAttrib; + * + * Code at time of setting new value has: + * + * uint8_t newValue = driver.GetNewValue(); + * auto now = SystemClock().GetMonotonicTimestamp(); + * if (mAttrib.SetValue(newValue, now) == AttributeDirtyState::kMustReport) + * { + * MatterReportingAttributeChangeCallback(path_for_attribute); + * } + * + * @tparam T - the type of underlying numerical value that will be held by the class. + */ +template ::value, bool> = true> +class QuieterReportingAttribute +{ +public: + explicit QuieterReportingAttribute(const Nullable & initialValue) : mValue(initialValue), mLastDirtyValue(initialValue) {} + + struct SufficientChangePredicateCandidate + { + // Timestamp of last time attribute was marked dirty. + Timestamp lastDirtyTimestamp; + // New (`now`) timestamp passed in `SetValue()`. + Timestamp nowTimestamp; + // Value last marked as dirty. + const Nullable & lastDirtyValue; + // New value passed in `SetValue()`, to compare against lastDirtyValue for sufficient change if needed. + const Nullable & newValue; + }; + + using SufficientChangePredicate = std::function; + + /** + * @brief Factory to generate a functor for "attribute was last reported" at least `minimumDurationMillis` ago. + * + * @param minimumDurationMillis - number of millis needed since last marked as dirty before we mark dirty again. + * @return a functor usable for the `changedPredicate` arg of `SetValue()` + */ + static SufficientChangePredicate + GetPredicateForSufficientTimeSinceLastDirty(System::Clock::Milliseconds64 minimumDurationMillis) + { + return [minimumDurationMillis](const SufficientChangePredicateCandidate & candidate) -> bool { + return (candidate.lastDirtyValue != candidate.newValue) && + ((candidate.nowTimestamp - candidate.lastDirtyTimestamp) >= minimumDurationMillis); + }; + } + + /** + * @brief Factory to generate a functor that forces reportable now. + * @return a functor usable for the `changedPredicate` arg of `SetValue()` + */ + static SufficientChangePredicate GetForceReportablePredicate() + { + return [](const SufficientChangePredicateCandidate & candidate) -> bool { return true; }; + } + + Nullable value() const { return mValue; } + QuieterReportingPolicyFlags & policy() { return mPolicyFlags; } + const QuieterReportingPolicyFlags & policy() const { return mPolicyFlags; } + + /** + * Set the updated value of the attribute, computing whether it needs to be reported according to `changedPredicate` and + * policies. + * + * - Any change of nullability between `newValue` and the old value will be considered dirty. + * - The policies from `QuieterReportingPolicyEnum` and set via `SetPolicy()` are self-explanatory by name. + * - The changedPredicate will be called with last dirty and new and may override + * the dirty state altogether when it returns true. Use sparingly and default to a functor returning false. + * + * Internal recording will be done about last dirty value and last dirty timestamp based on the policies having applied. + * + * @param newValue - new value to set for the attribute + * @param now - system monotonic timestamp at the time of the call + * @param changedPredicate - functor to possibly override dirty state + * @return AttributeDirtyState::kMustReport if attribute must be marked dirty right away, or + * AttributeDirtyState::kNoReportNeeded otherwise. + */ + AttributeDirtyState SetValue(const chip::app::DataModel::Nullable & newValue, Timestamp now, + SufficientChangePredicate changedPredicate) + { + bool isChangeOfNull = newValue.IsNull() ^ mValue.IsNull(); + bool areBothValuesNonNull = !newValue.IsNull() && !mValue.IsNull(); + + bool changeToFromZero = areBothValuesNonNull && (*newValue == 0 || *mValue == 0); + bool isIncrement = areBothValuesNonNull && (*newValue > *mValue); + bool isDecrement = areBothValuesNonNull && (*newValue < *mValue); + + bool isNewlyDirty = isChangeOfNull; + isNewlyDirty = + isNewlyDirty || (mPolicyFlags.Has(QuieterReportingPolicyEnum::kMarkDirtyOnChangeToFromZero) && changeToFromZero); + isNewlyDirty = isNewlyDirty || (mPolicyFlags.Has(QuieterReportingPolicyEnum::kMarkDirtyOnDecrement) && isDecrement); + isNewlyDirty = isNewlyDirty || (mPolicyFlags.Has(QuieterReportingPolicyEnum::kMarkDirtyOnIncrement) && isIncrement); + + SufficientChangePredicateCandidate candidate{ + mLastDirtyTimestampMillis, // lastDirtyTimestamp + now, // nowTimestamp + mLastDirtyValue, // lastDirtyValue + newValue // newValue + }; + isNewlyDirty = isNewlyDirty || changedPredicate(candidate); + + mValue = newValue; + + if (isNewlyDirty) + { + mLastDirtyValue = newValue; + mLastDirtyTimestampMillis = now; + } + + return isNewlyDirty ? AttributeDirtyState::kMustReport : AttributeDirtyState::kNoReportNeeded; + } + + /** + * Same as the other `SetValue`, but assumes a changedPredicate that never overrides to dirty. + * + * This is the easy/common case. + * + * @param newValue - new value to set for the attribute + * @param now - system monotonic timestamp at the time of the call + * @return AttributeDirtyState::kMustReport if attribute must be marked dirty right away, or + * AttributeDirtyState::kNoReportNeeded otherwise. + */ + AttributeDirtyState SetValue(const chip::app::DataModel::Nullable & newValue, Timestamp now) + { + return SetValue(newValue, now, [](const SufficientChangePredicateCandidate &) -> bool { return false; }); + } + +protected: + // Current value of the attribute. + chip::app::DataModel::Nullable mValue; + // Last value that was marked as dirty (to use in comparisons for change, e.g. by SufficientChangePredicate). + chip::app::DataModel::Nullable mLastDirtyValue; + // Enabled internal change detection policies. + QuieterReportingPolicyFlags mPolicyFlags{ 0 }; + // Timestamp associated with the last time the attribute was marked dirty (to use in comparisons for change). + chip::System::Clock::Milliseconds64 mLastDirtyTimestampMillis{}; +}; + +} // namespace detail + +using detail::QuieterReportingAttribute; + +} // namespace app +} // namespace chip diff --git a/src/app/cluster-building-blocks/tests/BUILD.gn b/src/app/cluster-building-blocks/tests/BUILD.gn new file mode 100644 index 00000000000000..540e139213ef73 --- /dev/null +++ b/src/app/cluster-building-blocks/tests/BUILD.gn @@ -0,0 +1,30 @@ +# 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/chip.gni") +import("${chip_root}/build/chip/chip_test_suite.gni") + +chip_test_suite("tests") { + output_name = "libAppClusterBuildingBlockTests" + + test_sources = [ "TestQuieterReporting.cpp" ] + + public_deps = [ + "${chip_root}/src/app/cluster-building-blocks", + "${chip_root}/src/app/data-model:nullable", + "${chip_root}/src/lib/core:error", + "${chip_root}/src/lib/support/tests:pw-test-macros", + "${chip_root}/src/system", + ] +} diff --git a/src/app/cluster-building-blocks/tests/TestQuieterReporting.cpp b/src/app/cluster-building-blocks/tests/TestQuieterReporting.cpp new file mode 100644 index 00000000000000..303d627029448e --- /dev/null +++ b/src/app/cluster-building-blocks/tests/TestQuieterReporting.cpp @@ -0,0 +1,262 @@ +/* + * + * 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 +#include + +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::DataModel; +using namespace chip::System::Clock; +using namespace chip::System::Clock::Literals; + +class FakeClock +{ +public: + FakeClock() = default; + + Timestamp Advance(Milliseconds64 numMillis) + { + mCurrentTimestamp += numMillis; + return mCurrentTimestamp; + } + + void SetMonotonic(Timestamp now) { mCurrentTimestamp = now; } + + Timestamp now() const { return mCurrentTimestamp; } + +private: + Timestamp mCurrentTimestamp{}; +}; + +TEST(TestQuieterReporting, ChangeToFromZeroPolicyWorks) +{ + FakeClock fakeClock; + fakeClock.SetMonotonic(100_ms); + + QuieterReportingAttribute attribute{ MakeNullable(10) }; + EXPECT_FALSE(attribute.value().IsNull()); + EXPECT_EQ(attribute.policy(), QuieterReportingPolicyFlags{}); + + auto now = fakeClock.now(); + + attribute.policy().Set(QuieterReportingPolicyEnum::kMarkDirtyOnChangeToFromZero); + EXPECT_TRUE(attribute.policy().HasOnly(QuieterReportingPolicyEnum::kMarkDirtyOnChangeToFromZero)); + + // 10 --> 11, expect not marked dirty yet. + EXPECT_EQ(attribute.SetValue(11, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // 11 --> 0, expect marked dirty. + EXPECT_EQ(attribute.SetValue(0, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 0); + + // 0 --> 11, expect marked dirty. + EXPECT_EQ(attribute.SetValue(11, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // 11 --> 12, expect not marked dirty. + EXPECT_EQ(attribute.SetValue(12, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 12); + + // Reset policy, expect 12 --> 0 does not mark dirty due to no longer having the policy that causes it. + attribute.policy().ClearAll(); + EXPECT_FALSE(attribute.policy().HasAny()); + + EXPECT_EQ(attribute.SetValue(0, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 0); +} + +TEST(TestQuieterReporting, ChangeOnIncrementPolicyWorks) +{ + FakeClock fakeClock; + fakeClock.SetMonotonic(100_ms); + + QuieterReportingAttribute attribute{ MakeNullable(10) }; + + // Always start not dirty (because first sub priming always just read value anyway). + ASSERT_EQ(*attribute.value(), 10); + + auto now = fakeClock.now(); + + attribute.policy().Set(QuieterReportingPolicyEnum::kMarkDirtyOnIncrement); + EXPECT_TRUE(attribute.policy().HasOnly(QuieterReportingPolicyEnum::kMarkDirtyOnIncrement)); + + // 10 --> 9, expect not marked dirty yet. + EXPECT_EQ(attribute.SetValue(9, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 9); + + // 9 --> 10, expect marked dirty. + EXPECT_EQ(attribute.SetValue(10, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 10); + + // 10 --> 11, expect marked dirty. + EXPECT_EQ(attribute.SetValue(11, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // 11 --> 11, expect marked not dirty. + EXPECT_EQ(attribute.SetValue(11, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // 11 --> null, expect marked dirty (null change always marks dirty) + EXPECT_EQ(attribute.SetValue(NullNullable, now), AttributeDirtyState::kMustReport); + EXPECT_TRUE(attribute.value().IsNull()); + + // null --> null, not dirty (no change) + EXPECT_EQ(attribute.SetValue(NullNullable, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_TRUE(attribute.value().IsNull()); + + // null --> 11, expect marked dirty (null change always marks dirty). + EXPECT_EQ(attribute.SetValue(11, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // Reset policy, expect 11 --> 12 does not mark dirty due to no longer having the policy that causes it. + attribute.policy().ClearAll(); + EXPECT_FALSE(attribute.policy().HasAny()); + + EXPECT_EQ(attribute.SetValue(12, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 12); +} + +TEST(TestQuieterReporting, ChangeOnDecrementPolicyWorks) +{ + FakeClock fakeClock; + fakeClock.SetMonotonic(100_ms); + + QuieterReportingAttribute attribute{ MakeNullable(9) }; + + // Always start not dirty (because first sub priming always just read value anyway). + ASSERT_EQ(*attribute.value(), 9); + + auto now = fakeClock.now(); + + attribute.policy().Set(QuieterReportingPolicyEnum::kMarkDirtyOnDecrement); + EXPECT_TRUE(attribute.policy().HasOnly(QuieterReportingPolicyEnum::kMarkDirtyOnDecrement)); + + // 9 --> 10, expect not marked dirty yet. + EXPECT_EQ(attribute.SetValue(10, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 10); + + // 10 --> 9, expect marked dirty. + EXPECT_EQ(attribute.SetValue(9, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 9); + + // 9 --> 8, expect marked dirty. + EXPECT_EQ(attribute.SetValue(8, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 8); + + // Second call in a row always false. + + // 8 --> 8, expect not marked dirty. + EXPECT_EQ(attribute.SetValue(8, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 8); + + // 8 --> null, expect marked dirty (null change always marks dirty) + EXPECT_EQ(attribute.SetValue(NullNullable, now), AttributeDirtyState::kMustReport); + EXPECT_TRUE(attribute.value().IsNull()); + + // null --> null, not dirty (no change) + EXPECT_EQ(attribute.SetValue(NullNullable, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_TRUE(attribute.value().IsNull()); + + // null --> 11, expect marked dirty (null change always marks dirty). + EXPECT_EQ(attribute.SetValue(11, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // Reset policy, expect 11 --> 10 does not mark dirty due to no longer having the policy that causes it. + attribute.policy().ClearAll(); + EXPECT_FALSE(attribute.policy().HasAny()); + + EXPECT_EQ(attribute.SetValue(10, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 10); +} + +TEST(TestQuieterReporting, SufficientChangePredicateWorks) +{ + FakeClock fakeClock; + fakeClock.SetMonotonic(100_ms); + + QuieterReportingAttribute attribute{ MakeNullable(9) }; + + // Always start not dirty (because first sub priming always just read value anyway). + ASSERT_EQ(*attribute.value(), 9); + + auto now = fakeClock.now(); + + EXPECT_EQ(attribute.SetValue(10, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 10); + + // Forcing dirty can be done with a force-true predicate + EXPECT_EQ(attribute.SetValue(10, now, attribute.GetForceReportablePredicate()), AttributeDirtyState::kMustReport); + + auto predicate = attribute.GetPredicateForSufficientTimeSinceLastDirty(1000_ms); + + now = fakeClock.Advance(100_ms); + + // Last dirty value is 10. This won't mark dirty again due to predicate mismatch. + EXPECT_EQ(attribute.SetValue(11, now, predicate), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + now = fakeClock.Advance(900_ms); + // Last dirty value is 10 still. This will mark dirty because both enough time has passed + // and value is different from the last dirty value. + EXPECT_EQ(attribute.SetValue(11, now, predicate), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // Last dirty value is 11. Since there has not been a value change, no amount of time will + // mark dirty. + now = fakeClock.Advance(1000_ms); + EXPECT_EQ(attribute.SetValue(11, now, predicate), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + now = fakeClock.Advance(1000_ms); + EXPECT_EQ(attribute.SetValue(11, now, predicate), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // Change the value to a value that marks dirty. + now = fakeClock.Advance(1_ms); + EXPECT_EQ(attribute.SetValue(12, now, predicate), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 12); + + // Wait a small delay and change again. Will not mark dirty due to too little time. + now = fakeClock.Advance(1_ms); + EXPECT_EQ(attribute.SetValue(13, now, predicate), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 13); + + now = fakeClock.Advance(1_ms); + EXPECT_EQ(attribute.SetValue(14, now, predicate), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 14); + + // Change to a value that marks dirty no matter what (e.g. null). Should be dirty even + // before delay. + now = fakeClock.Advance(1_ms); + EXPECT_EQ(attribute.SetValue(NullNullable, now, predicate), AttributeDirtyState::kMustReport); + EXPECT_TRUE(attribute.value().IsNull()); + + // Null --> Null should not lead to dirty. + now = fakeClock.Advance(1000_ms); + EXPECT_EQ(attribute.SetValue(NullNullable, now, predicate), AttributeDirtyState::kNoReportNeeded); + EXPECT_TRUE(attribute.value().IsNull()); +} diff --git a/src/app/clusters/descriptor/descriptor.cpp b/src/app/clusters/descriptor/descriptor.cpp index 4eb68621c5767e..514051226fdcf5 100644 --- a/src/app/clusters/descriptor/descriptor.cpp +++ b/src/app/clusters/descriptor/descriptor.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -206,9 +205,7 @@ CHIP_ERROR DescriptorAttrAccess::ReadClusterRevision(EndpointId endpoint, Attrib return aEncoder.Encode(kClusterRevision); } -namespace { -Global gAttrAccess; -} +DescriptorAttrAccess gAttrAccess; CHIP_ERROR DescriptorAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) { @@ -247,5 +244,5 @@ CHIP_ERROR DescriptorAttrAccess::Read(const ConcreteReadAttributePath & aPath, A void MatterDescriptorPluginServerInitCallback() { - registerAttributeAccessOverride(&gAttrAccess.get()); + registerAttributeAccessOverride(&gAttrAccess); } diff --git a/src/app/clusters/door-lock-server/door-lock-server.cpp b/src/app/clusters/door-lock-server/door-lock-server.cpp index 528cbd6eb0971d..68e5f398b5bc84 100644 --- a/src/app/clusters/door-lock-server/door-lock-server.cpp +++ b/src/app/clusters/door-lock-server/door-lock-server.cpp @@ -51,39 +51,6 @@ static constexpr uint8_t DOOR_LOCK_ALIRO_CREDENTIAL_SIZE = 65; static constexpr uint32_t DOOR_LOCK_MAX_LOCK_TIMEOUT_SEC = MAX_INT32U_VALUE / MILLISECOND_TICKS_PER_SECOND; -static constexpr size_t kDoorLockDelegateTableSize = - MATTER_DM_DOOR_LOCK_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; - -static_assert(kDoorLockDelegateTableSize <= kEmberInvalidEndpointIndex, "Door Lock Delegate table size error"); - -namespace chip { -namespace app { -namespace Clusters { -namespace DoorLock { - -Delegate * gDelegateTable[kDoorLockDelegateTableSize] = { nullptr }; - -Delegate * GetDelegate(EndpointId endpoint) -{ - uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, DoorLock::Id, MATTER_DM_DOOR_LOCK_CLUSTER_SERVER_ENDPOINT_COUNT); - return (ep >= kDoorLockDelegateTableSize ? nullptr : gDelegateTable[ep]); -} - -void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) -{ - uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, DoorLock::Id, MATTER_DM_DOOR_LOCK_CLUSTER_SERVER_ENDPOINT_COUNT); - // if endpoint is found - if (ep < ArraySize(gDelegateTable)) - { - gDelegateTable[ep] = delegate; - } -} - -} // namespace DoorLock -} // namespace Clusters -} // namespace app -} // namespace chip - DoorLockServer DoorLockServer::instance; class DoorLockClusterFabricDelegate : public chip::FabricTable::Delegate @@ -117,7 +84,18 @@ DoorLockServer & DoorLockServer::Instance() * * @param endpointId */ -void DoorLockServer::InitServer(chip::EndpointId endpointId) +void DoorLockServer::InitServer(EndpointId endpointId) +{ + CHIP_ERROR err = InitEndpoint(endpointId); + + // We have no way to communicate this error, so just log it. + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Door Lock cluster initialization on endpoint %d failed: %" CHIP_ERROR_FORMAT, endpointId, err.Format()); + } +} + +CHIP_ERROR DoorLockServer::InitEndpoint(EndpointId endpointId, Delegate * delegate) { ChipLogProgress(Zcl, "Door Lock cluster initialized at endpoint #%u", endpointId); @@ -128,11 +106,48 @@ void DoorLockServer::InitServer(chip::EndpointId endpointId) } SetActuatorEnabled(endpointId, true); - for (auto & ep : mEndpointCtx) + auto * endpointContext = getContext(endpointId); + if (!endpointContext) { - ep.lockoutEndTimestamp = ep.lockoutEndTimestamp.zero(); - ep.wrongCodeEntryAttempts = 0; + ChipLogError(Zcl, "Invalid endpoint %d for initializing lock server: no endpoint context available", endpointId); + return CHIP_ERROR_INVALID_ARGUMENT; } + + endpointContext->lockoutEndTimestamp = endpointContext->lockoutEndTimestamp.zero(); + endpointContext->wrongCodeEntryAttempts = 0; + endpointContext->delegate = delegate; + return CHIP_NO_ERROR; +} + +void DoorLockServer::ShutdownEndpoint(EndpointId endpointId) +{ + auto * endpointContext = getContext(endpointId); + if (!endpointContext) + { + ChipLogError(Zcl, "Invalid endpoint %d for shutting down lock server: no endpoint context available", endpointId); + return; + } + + endpointContext->delegate = nullptr; +} + +CHIP_ERROR DoorLockServer::SetDelegate(chip::EndpointId endpointId, chip::app::Clusters::DoorLock::Delegate * delegate) +{ + if (!delegate) + { + ChipLogError(Zcl, "Trying to set a null DoorLock::Delegate on endpoint %d", endpointId); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + auto * endpointContext = getContext(endpointId); + if (!endpointContext) + { + ChipLogError(Zcl, "Invalid endpoint %d for setting a delegate: no endpoint context available", endpointId); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + endpointContext->delegate = delegate; + return CHIP_NO_ERROR; } bool DoorLockServer::SetLockState(chip::EndpointId endpointId, DlLockState newLockState) @@ -942,7 +957,18 @@ void DoorLockServer::clearCredentialCommandHandler( } // Remove all the credentials of the particular type. - auto credentialType = credential.Value().credentialType; + auto credentialType = credential.Value().credentialType; + + if (!credentialTypeSupported(commandPath.mEndpointId, credentialType)) + { + ChipLogProgress(Zcl, + "[ClearCredential] Credential type is not supported [endpointId=%d,credentialType=%u" + "]", + commandPath.mEndpointId, to_underlying(credentialType)); + commandObj->AddStatus(commandPath, Status::InvalidCommand); + return; + } + auto credentialIndex = credential.Value().credentialIndex; if (0xFFFE == credentialIndex) { @@ -2395,6 +2421,42 @@ DlStatus DoorLockServer::createCredential(chip::EndpointId endpointId, chip::Fab return DlStatus::kInvalidField; } + // For Aliro endpoint keys, there is a single shared count for the total + // count of evictable and non-evictable keys that can be stored. This needs + // to be enforced specially, because none of the other logic we have handles that. + if (credentialType == CredentialTypeEnum::kAliroEvictableEndpointKey || + credentialType == CredentialTypeEnum::kAliroNonEvictableEndpointKey) + { + Delegate * delegate = GetDelegate(endpointId); + if (delegate == nullptr) + { + ChipLogError(Zcl, "Door lock delegate is null, can't handle Aliro credentials"); + return DlStatus::kFailure; + } + + size_t maxEndpointKeys = delegate->GetNumberOfAliroEndpointKeysSupported(); + size_t evictableEndpointKeys, nonEvictableEndpointKeys; + + if (!countOccupiedCredentials(endpointId, CredentialTypeEnum::kAliroEvictableEndpointKey, evictableEndpointKeys)) + { + ChipLogError(Zcl, "Unable to count Aliro evictable endpoint keys."); + return DlStatus::kFailure; + } + + if (!countOccupiedCredentials(endpointId, CredentialTypeEnum::kAliroNonEvictableEndpointKey, nonEvictableEndpointKeys)) + { + ChipLogError(Zcl, "Unable to count Aliro non-evictable endpoint keys."); + return DlStatus::kFailure; + } + + if (evictableEndpointKeys + nonEvictableEndpointKeys >= maxEndpointKeys) + { + // We have no space for another credential here. + ChipLogError(Zcl, "Unable to create Aliro endpoint key credential; too many exist already [endpointId=%d]", endpointId); + return DlStatus::kResourceExhausted; + } + } + CredentialStruct credential{ credentialType, credentialIndex }; // appclusters, 5.2.4.40: if userIndex is not provided we should create new user DlStatus status = DlStatus::kSuccess; @@ -2432,6 +2494,42 @@ DlStatus DoorLockServer::createCredential(chip::EndpointId endpointId, chip::Fab return status; } +bool DoorLockServer::countOccupiedCredentials(chip::EndpointId endpointId, CredentialTypeEnum credentialType, + size_t & occupiedCount) +{ + uint16_t maxCredentialCount; + + if (!getMaxNumberOfCredentials(endpointId, credentialType, maxCredentialCount)) + { + return false; + } + + uint16_t startIndex = 1; + // Programming PIN is a special case -- it is unique and its index assumed to be 0. + if (CredentialTypeEnum::kProgrammingPIN == credentialType) + { + startIndex = 0; + maxCredentialCount--; + } + + occupiedCount = 0; + for (uint16_t credentialIndex = startIndex; credentialIndex <= maxCredentialCount; ++credentialIndex) + { + EmberAfPluginDoorLockCredentialInfo credential; + if (!emberAfPluginDoorLockGetCredential(endpointId, credentialIndex, credentialType, credential)) + { + return false; + } + + if (credential.status == DlCredentialStatus::kOccupied) + { + ++occupiedCount; + } + } + + return true; +} + DlStatus DoorLockServer::modifyProgrammingPIN(chip::EndpointId endpointId, chip::FabricIndex modifierFabricIndex, chip::NodeId sourceNodeId, uint16_t credentialIndex, CredentialTypeEnum credentialType, @@ -2908,28 +3006,6 @@ Status DoorLockServer::clearCredential(chip::EndpointId endpointId, chip::Fabric return Status::Failure; } - uint8_t maxCredentialsPerUser; - if (!GetNumberOfCredentialsSupportedPerUser(endpointId, maxCredentialsPerUser)) - { - ChipLogError(Zcl, - "[clearCredential] Unable to get the number of available credentials per user: internal error " - "[endpointId=%d,credentialType=%d,credentialIndex=%d]", - endpointId, to_underlying(credentialType), credentialIndex); - return Status::Failure; - } - - // Should never happen, only possible if the implementation of application is incorrect - if (relatedUser.credentials.size() > maxCredentialsPerUser) - { - ChipLogError(Zcl, - "[clearCredential] Unable to clear credential for related user - user has too many credentials associated" - "[endpointId=%d,credentialType=%u,credentialIndex=%d,modifier=%d,userIndex=%d,credentialsCount=%u]", - endpointId, to_underlying(credentialType), credentialIndex, modifier, relatedUserIndex, - static_cast(relatedUser.credentials.size())); - - return Status::Failure; - } - chip::Platform::ScopedMemoryBuffer newCredentials; if (!newCredentials.Alloc(relatedUser.credentials.size())) { @@ -3445,6 +3521,17 @@ EmberAfDoorLockEndpointContext * DoorLockServer::getContext(chip::EndpointId end return nullptr; } +Delegate * DoorLockServer::GetDelegate(EndpointId endpointId) +{ + auto * endpointContext = getContext(endpointId); + if (!endpointContext) + { + return nullptr; + } + + return endpointContext->delegate; +} + bool DoorLockServer::HandleRemoteLockOperation(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, LockOperationTypeEnum opType, RemoteLockOpHandler opHandler, const Optional & pinCode) @@ -3918,14 +4005,6 @@ void DoorLockServer::setAliroReaderConfigCommandHandler(CommandHandler * command EndpointId endpointID = commandPath.mEndpointId; ChipLogProgress(Zcl, "[SetAliroReaderConfig] Incoming command [endpointId=%d]", endpointID); - // If Aliro Provisioning feature is not supported, return UNSUPPORTED_COMMAND. - if (!SupportsAliroProvisioning(endpointID)) - { - ChipLogProgress(Zcl, "[SetAliroReaderConfig] Aliro Provisioning is not supported [endpointId=%d]", endpointID); - commandObj->AddStatus(commandPath, Status::UnsupportedCommand); - return; - } - Delegate * delegate = GetDelegate(endpointID); if (!delegate) { @@ -3988,10 +4067,7 @@ void DoorLockServer::setAliroReaderConfigCommandHandler(CommandHandler * command // Various attributes changed; mark them dirty. MatterReportingAttributeChangeCallback(endpointID, Clusters::DoorLock::Id, AliroReaderVerificationKey::Id); MatterReportingAttributeChangeCallback(endpointID, Clusters::DoorLock::Id, AliroReaderGroupIdentifier::Id); - if (supportsAliroBLEUWB) - { - MatterReportingAttributeChangeCallback(endpointID, Clusters::DoorLock::Id, AliroGroupResolvingKey::Id); - } + MatterReportingAttributeChangeCallback(endpointID, Clusters::DoorLock::Id, AliroGroupResolvingKey::Id); } sendClusterResponse(commandObj, commandPath, ClusterStatusCode(StatusIB(err).mStatus)); } @@ -4001,14 +4077,6 @@ void DoorLockServer::clearAliroReaderConfigCommandHandler(CommandHandler * comma EndpointId endpointID = commandPath.mEndpointId; ChipLogProgress(Zcl, "[ClearAliroReaderConfig] Incoming command [endpointId=%d]", endpointID); - // If Aliro Provisioning feature is not supported, return UNSUPPORTED_COMMAND. - if (!SupportsAliroProvisioning(endpointID)) - { - ChipLogProgress(Zcl, "[ClearAliroReaderConfig] Aliro Provisioning is not supported [endpointId=%d]", endpointID); - commandObj->AddStatus(commandPath, Status::UnsupportedCommand); - return; - } - Delegate * delegate = GetDelegate(endpointID); if (!delegate) { @@ -4038,10 +4106,7 @@ void DoorLockServer::clearAliroReaderConfigCommandHandler(CommandHandler * comma // Various attributes changed; mark them dirty. MatterReportingAttributeChangeCallback(endpointID, Clusters::DoorLock::Id, AliroReaderVerificationKey::Id); MatterReportingAttributeChangeCallback(endpointID, Clusters::DoorLock::Id, AliroReaderGroupIdentifier::Id); - if (SupportsAliroBLEUWB(endpointID)) - { - MatterReportingAttributeChangeCallback(endpointID, Clusters::DoorLock::Id, AliroGroupResolvingKey::Id); - } + MatterReportingAttributeChangeCallback(endpointID, Clusters::DoorLock::Id, AliroGroupResolvingKey::Id); } sendClusterResponse(commandObj, commandPath, ClusterStatusCode(StatusIB(err).mStatus)); } @@ -4203,8 +4268,7 @@ void DoorLockServer::DoorLockOnAutoRelockCallback(System::Layer *, void * callba } } -CHIP_ERROR DoorLockServer::ReadAliroExpeditedTransactionSupportedProtocolVersions(const ConcreteReadAttributePath & aPath, - AttributeValueEncoder & aEncoder, +CHIP_ERROR DoorLockServer::ReadAliroExpeditedTransactionSupportedProtocolVersions(AttributeValueEncoder & aEncoder, Delegate * delegate) { VerifyOrReturnValue(delegate != nullptr, aEncoder.EncodeEmptyList()); @@ -4225,8 +4289,7 @@ CHIP_ERROR DoorLockServer::ReadAliroExpeditedTransactionSupportedProtocolVersion }); } -CHIP_ERROR DoorLockServer::ReadAliroSupportedBLEUWBProtocolVersions(const ConcreteReadAttributePath & aPath, - AttributeValueEncoder & aEncoder, Delegate * delegate) +CHIP_ERROR DoorLockServer::ReadAliroSupportedBLEUWBProtocolVersions(AttributeValueEncoder & aEncoder, Delegate * delegate) { VerifyOrReturnValue(delegate != nullptr, aEncoder.EncodeEmptyList()); @@ -4296,7 +4359,7 @@ CHIP_ERROR DoorLockServer::Read(const ConcreteReadAttributePath & aPath, Attribu AttributeNullabilityType::kNotNullable); } case AliroExpeditedTransactionSupportedProtocolVersions::Id: { - return ReadAliroExpeditedTransactionSupportedProtocolVersions(aPath, aEncoder, delegate); + return ReadAliroExpeditedTransactionSupportedProtocolVersions(aEncoder, delegate); } case AliroGroupResolvingKey::Id: { uint8_t buffer[kAliroGroupResolvingKeySize]; @@ -4305,7 +4368,7 @@ CHIP_ERROR DoorLockServer::Read(const ConcreteReadAttributePath & aPath, Attribu AttributeNullabilityType::kNullable); } case AliroSupportedBLEUWBProtocolVersions::Id: { - return ReadAliroSupportedBLEUWBProtocolVersions(aPath, aEncoder, delegate); + return ReadAliroSupportedBLEUWBProtocolVersions(aEncoder, delegate); } case AliroBLEAdvertisingVersion::Id: { uint8_t bleAdvertisingVersion = delegate->GetAliroBLEAdvertisingVersion(); diff --git a/src/app/clusters/door-lock-server/door-lock-server.h b/src/app/clusters/door-lock-server/door-lock-server.h index 6941a3c580826d..81b18c60e687e8 100644 --- a/src/app/clusters/door-lock-server/door-lock-server.h +++ b/src/app/clusters/door-lock-server/door-lock-server.h @@ -86,20 +86,9 @@ struct EmberAfDoorLockEndpointContext { chip::System::Clock::Timestamp lockoutEndTimestamp; int wrongCodeEntryAttempts; + chip::app::Clusters::DoorLock::Delegate * delegate = nullptr; }; -namespace chip { -namespace app { -namespace Clusters { -namespace DoorLock { - -void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate); - -} // namespace DoorLock -} // namespace Clusters -} // namespace app -} // namespace chip - /** * @brief Door Lock Server Plugin class. */ @@ -112,7 +101,28 @@ class DoorLockServer : public chip::app::AttributeAccessInterface using Feature = chip::app::Clusters::DoorLock::Feature; using OnFabricRemovedCustomCallback = void (*)(chip::EndpointId endpointId, chip::FabricIndex fabricIndex); - void InitServer(chip::EndpointId endpointId); + /** + * Multiple InitEndpoint calls can happen for different endpoints. Calling + * InitEndpoint twice for the same endpoint requires a ShutdownEndpoint call + * for that endpoint in between. + * + * A DoorLock::Delegate is optional, but needs to be provided in either + * InitEndpoint or in a separate SetDelegate call for Aliro features, and + * possibly other new features, to work. + */ + CHIP_ERROR InitEndpoint(chip::EndpointId endpointId, chip::app::Clusters::DoorLock::Delegate * delegate = nullptr); + + void ShutdownEndpoint(chip::EndpointId endpointId); + + // InitServer is a deprecated alias for InitEndpoint with no delegate. + void InitServer(chip::EndpointId endpointid); + + /** + * Delegate is not supposed to be null. Removing a delegate + * should only happen when shutting down the door lock cluster on the + * endpoint, via ShutdownEndpoint. + */ + CHIP_ERROR SetDelegate(chip::EndpointId endpointId, chip::app::Clusters::DoorLock::Delegate * delegate); /** * Updates the LockState attribute with new value and sends LockOperation event. @@ -350,6 +360,12 @@ class DoorLockServer : public chip::app::AttributeAccessInterface const EmberAfPluginDoorLockCredentialInfo & existingCredential, const chip::ByteSpan & credentialData, Nullable userIndex, const Nullable & userStatus, Nullable userType, uint16_t & createdUserIndex); + /** + * countOccupiedCredentials counts the number of occupied credentials of the + * given type. Returns false on application-side errors (i.e. if the count + * cannot be determined). + */ + bool countOccupiedCredentials(chip::EndpointId endpointId, CredentialTypeEnum credentialType, size_t & occupiedCount); DlStatus modifyProgrammingPIN(chip::EndpointId endpointId, chip::FabricIndex modifierFabricIndex, chip::NodeId sourceNodeId, uint16_t credentialIndex, CredentialTypeEnum credentialType, const EmberAfPluginDoorLockCredentialInfo & existingCredential, @@ -488,6 +504,13 @@ class DoorLockServer : public chip::app::AttributeAccessInterface static void sendClusterResponse(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, chip::Protocols::InteractionModel::ClusterStatusCode status); + /** + * Get the DoorLock::Delegate for the given endpoint, if any. Will return + * null if there is no door lock server initialized on that endpoint or if + * there is no delegate associated with the initialized server. + */ + chip::app::Clusters::DoorLock::Delegate * GetDelegate(chip::EndpointId endpointId); + /** * @brief Common handler for LockDoor, UnlockDoor, UnlockWithTimeout commands * @@ -576,29 +599,25 @@ class DoorLockServer : public chip::app::AttributeAccessInterface /** * @brief Reads AliroExpeditedTransactionSupportedProtocolVersions attribute for door lock * - * @param aPath attribute path. * @param aEncoder attribute value encoder. * @param delegate door lock cluster delegate that will provide the value * * @return CHIP_NO_ERROR on success * @return CHIP_ERROR if attribute read failed */ - CHIP_ERROR ReadAliroExpeditedTransactionSupportedProtocolVersions(const chip::app::ConcreteReadAttributePath & aPath, - chip::app::AttributeValueEncoder & aEncoder, + CHIP_ERROR ReadAliroExpeditedTransactionSupportedProtocolVersions(chip::app::AttributeValueEncoder & aEncoder, chip::app::Clusters::DoorLock::Delegate * delegate); /** * @brief Reads AliroSupportedBLEUWBProtocolVersions attribute for door lock * - * @param aPath attribute path. * @param aEncoder attribute value encoder. * @param delegate door lock cluster delegate that will provide the value * * @return CHIP_NO_ERROR on success * @return CHIP_ERROR if attribute read failed */ - CHIP_ERROR ReadAliroSupportedBLEUWBProtocolVersions(const chip::app::ConcreteReadAttributePath & aPath, - chip::app::AttributeValueEncoder & aEncoder, + CHIP_ERROR ReadAliroSupportedBLEUWBProtocolVersions(chip::app::AttributeValueEncoder & aEncoder, chip::app::Clusters::DoorLock::Delegate * delegate); /** diff --git a/src/app/clusters/time-synchronization-server/time-synchronization-server.h b/src/app/clusters/time-synchronization-server/time-synchronization-server.h index 2581c9712e7862..ecc9a68cc3fc12 100644 --- a/src/app/clusters/time-synchronization-server/time-synchronization-server.h +++ b/src/app/clusters/time-synchronization-server/time-synchronization-server.h @@ -124,9 +124,10 @@ class TimeSynchronizationServer : public FabricTable::Delegate void OnAttributeData(const ConcreteDataAttributePath & aPath, TLV::TLVReader * apData, const StatusIB & aStatus) override; void OnDone(ReadClient * apReadClient) override; - CHIP_ERROR AttemptToGetTimeFromTrustedNode(); #endif + CHIP_ERROR AttemptToGetTimeFromTrustedNode(); + // Platform event handler functions void OnPlatformEventFn(const DeviceLayer::ChipDeviceEvent & event); diff --git a/src/app/codegen-data-model/CodegenDataModel.cpp b/src/app/codegen-data-model/CodegenDataModel.cpp index 0cc9b42aaa64f7..851f7c341ab127 100644 --- a/src/app/codegen-data-model/CodegenDataModel.cpp +++ b/src/app/codegen-data-model/CodegenDataModel.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -232,10 +233,19 @@ bool CodegenDataModel::EmberCommandListIterator::Exists(const CommandId * list, } CHIP_ERROR CodegenDataModel::Invoke(const InteractionModel::InvokeRequest & request, TLV::TLVReader & input_arguments, - InteractionModel::InvokeReply & reply) + CommandHandler * handler) { - // TODO: this needs an implementation - return CHIP_ERROR_NOT_IMPLEMENTED; + // TODO: CommandHandlerInterface support is currently + // residing in InteractionModelEngine itself. We may want to separate this out + // into its own registry, similar to attributes, so that IM is decoupled from actual storage of things. + // + // Open issue at https://github.com/project-chip/connectedhomeip/issues/34258 + + // Ember dispatching automatically uses `handler` to set an appropriate result or status + // This never fails (as handler error is encoded as needed). + DispatchSingleClusterCommand(request.path, input_arguments, handler); + + return CHIP_NO_ERROR; } EndpointId CodegenDataModel::FirstEndpoint() diff --git a/src/app/codegen-data-model/CodegenDataModel.h b/src/app/codegen-data-model/CodegenDataModel.h index b65f38b9155e73..123dcd72382291 100644 --- a/src/app/codegen-data-model/CodegenDataModel.h +++ b/src/app/codegen-data-model/CodegenDataModel.h @@ -71,7 +71,7 @@ class CodegenDataModel : public chip::app::InteractionModel::DataModel CHIP_ERROR ReadAttribute(const InteractionModel::ReadAttributeRequest & request, AttributeValueEncoder & encoder) override; CHIP_ERROR WriteAttribute(const InteractionModel::WriteAttributeRequest & request, AttributeValueDecoder & decoder) override; CHIP_ERROR Invoke(const InteractionModel::InvokeRequest & request, chip::TLV::TLVReader & input_arguments, - InteractionModel::InvokeReply & reply) override; + CommandHandler * handler) override; /// attribute tree iteration EndpointId FirstEndpoint() override; diff --git a/src/app/codegen-data-model/tests/BUILD.gn b/src/app/codegen-data-model/tests/BUILD.gn index 3d265a96a66b29..3f88ac61c41766 100644 --- a/src/app/codegen-data-model/tests/BUILD.gn +++ b/src/app/codegen-data-model/tests/BUILD.gn @@ -24,6 +24,8 @@ source_set("ember_extra_files") { "${chip_root}/src/app/util/ember-io-storage.cpp", "AttributeReportIBEncodeDecode.cpp", "AttributeReportIBEncodeDecode.h", + "EmberInvokeOverride.cpp", + "EmberInvokeOverride.h", "EmberReadWriteOverride.cpp", "EmberReadWriteOverride.h", "InteractionModelTemporaryOverrides.cpp", diff --git a/src/app/codegen-data-model/tests/EmberInvokeOverride.cpp b/src/app/codegen-data-model/tests/EmberInvokeOverride.cpp new file mode 100644 index 00000000000000..552e0be3d966ff --- /dev/null +++ b/src/app/codegen-data-model/tests/EmberInvokeOverride.cpp @@ -0,0 +1,55 @@ +/* + * 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 "EmberInvokeOverride.h" + +#include + +namespace { + +chip::app::ConcreteCommandPath gLastDispatchPath; +uint32_t gDispatchCount = 0; + +} // namespace + +namespace chip { +namespace Test { + +app::ConcreteCommandPath GetLastDispatchPath() +{ + return gLastDispatchPath; +} + +uint32_t DispatchCount() +{ + return gDispatchCount; +} + +} // namespace Test +} // namespace chip + +namespace chip { +namespace app { + +void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPath, chip::TLV::TLVReader & aReader, + CommandHandler * apCommandObj) +{ + gLastDispatchPath = aRequestCommandPath; + gDispatchCount++; +} + +} // namespace app +} // namespace chip diff --git a/src/app/codegen-data-model/tests/EmberInvokeOverride.h b/src/app/codegen-data-model/tests/EmberInvokeOverride.h new file mode 100644 index 00000000000000..d2f7b5c32fb1f8 --- /dev/null +++ b/src/app/codegen-data-model/tests/EmberInvokeOverride.h @@ -0,0 +1,31 @@ +/* + * 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 + +namespace chip { +namespace Test { + +/// what was the last path on which DispatchSingleClusterCommand was called +app::ConcreteCommandPath GetLastDispatchPath(); + +/// How many times was DispatchSingleClusterCommand called +uint32_t DispatchCount(); + +} // namespace Test +} // namespace chip diff --git a/src/app/codegen-data-model/tests/InteractionModelTemporaryOverrides.cpp b/src/app/codegen-data-model/tests/InteractionModelTemporaryOverrides.cpp index a595acc81f3b5c..e771827adf18f6 100644 --- a/src/app/codegen-data-model/tests/InteractionModelTemporaryOverrides.cpp +++ b/src/app/codegen-data-model/tests/InteractionModelTemporaryOverrides.cpp @@ -74,12 +74,6 @@ CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescr return CHIP_ERROR_NOT_IMPLEMENTED; } -void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPath, chip::TLV::TLVReader & aReader, - CommandHandler * apCommandObj) -{ - // TODO: total hardcoded noop -} - } // namespace app } // namespace chip diff --git a/src/app/codegen-data-model/tests/TestCodegenModelViaMocks.cpp b/src/app/codegen-data-model/tests/TestCodegenModelViaMocks.cpp index 2bf88a02bae6ef..e0fd4f6148f7c4 100644 --- a/src/app/codegen-data-model/tests/TestCodegenModelViaMocks.cpp +++ b/src/app/codegen-data-model/tests/TestCodegenModelViaMocks.cpp @@ -14,9 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "app/ConcreteCommandPath.h" #include #include +#include #include #include @@ -69,6 +71,9 @@ constexpr NodeId kTestNodeId = 0xFFFF'1234'ABCD'4321; constexpr AttributeId kAttributeIdReadOnly = 0x3001; constexpr AttributeId kAttributeIdTimedWrite = 0x3002; +constexpr CommandId kMockCommandId1 = 0x1234; +constexpr CommandId kMockCommandId2 = 0x1122; + constexpr EndpointId kEndpointIdThatIsMissing = kMockEndpointMin - 1; constexpr AttributeId kReadOnlyAttributeId = 0x5001; @@ -2430,6 +2435,47 @@ TEST(TestCodegenModelViaMocks, EmberWriteAttributeAccessInterfaceTest) TestEmberScalarNullWrite(); } +TEST(TestCodegenModelViaMocks, EmberInvokeTest) +{ + // Ember invoke is fully code-generated - there is a single function for Dispatch + // that will do a `switch` on the path elements and invoke a corresponding `emberAf*` + // callback. + // + // The only thing that can be validated is that this `DispatchSingleClusterCommand` + // is actually invoked. + + UseMockNodeConfig config(gTestNodeConfig); + chip::app::CodegenDataModel model; + + { + const ConcreteCommandPath kCommandPath(kMockEndpoint1, MockClusterId(1), kMockCommandId1); + const InvokeRequest kInvokeRequest{ .path = kCommandPath }; + chip::TLV::TLVReader tlvReader; + + const uint32_t kDispatchCountPre = chip::Test::DispatchCount(); + + // Using a handler set to nullptr as it is not used by the impl + ASSERT_EQ(model.Invoke(kInvokeRequest, tlvReader, /* handler = */ nullptr), CHIP_NO_ERROR); + + EXPECT_EQ(chip::Test::DispatchCount(), kDispatchCountPre + 1); // single dispatch + EXPECT_EQ(chip::Test::GetLastDispatchPath(), kCommandPath); // for the right path + } + + { + const ConcreteCommandPath kCommandPath(kMockEndpoint1, MockClusterId(1), kMockCommandId2); + const InvokeRequest kInvokeRequest{ .path = kCommandPath }; + chip::TLV::TLVReader tlvReader; + + const uint32_t kDispatchCountPre = chip::Test::DispatchCount(); + + // Using a handler set to nullpotr as it is not used by the impl + ASSERT_EQ(model.Invoke(kInvokeRequest, tlvReader, /* handler = */ nullptr), CHIP_NO_ERROR); + + EXPECT_EQ(chip::Test::DispatchCount(), kDispatchCountPre + 1); // single dispatch + EXPECT_EQ(chip::Test::GetLastDispatchPath(), kCommandPath); // for the right path + } +} + TEST(TestCodegenModelViaMocks, EmberWriteAttributeAccessInterfaceReturningError) { UseMockNodeConfig config(gTestNodeConfig); diff --git a/src/app/data-model-interface/BUILD.gn b/src/app/data-model-interface/BUILD.gn index 65cde75612e2ba..abe66a68f342bd 100644 --- a/src/app/data-model-interface/BUILD.gn +++ b/src/app/data-model-interface/BUILD.gn @@ -20,7 +20,6 @@ source_set("data-model-interface") { "DataModel.h", "DataModelChangeListener.h", "EventsGenerator.h", - "InvokeResponder.h", "MetadataTypes.cpp", "MetadataTypes.h", "OperationTypes.h", @@ -29,6 +28,7 @@ source_set("data-model-interface") { public_deps = [ "${chip_root}/src/access:types", "${chip_root}/src/app:attribute-access", + "${chip_root}/src/app:command-handler-interface", "${chip_root}/src/app:events", "${chip_root}/src/app:paths", "${chip_root}/src/app/MessageDef", diff --git a/src/app/data-model-interface/DataModel.h b/src/app/data-model-interface/DataModel.h index d673b79aac72a9..bcf24c1aa9e7b2 100644 --- a/src/app/data-model-interface/DataModel.h +++ b/src/app/data-model-interface/DataModel.h @@ -21,9 +21,9 @@ #include #include +#include #include -#include #include #include @@ -99,25 +99,9 @@ class DataModel : public DataModelMetadataTree /// - `NeedsTimedInteraction` for writes that are not timed however are required to be so virtual CHIP_ERROR WriteAttribute(const WriteAttributeRequest & request, AttributeValueDecoder & decoder) = 0; - /// `reply` is used to send back the reply. - /// - calling Reply() or ReplyAsync() will let the application control the reply - /// - returning a CHIP_NO_ERROR without reply/reply_async implies a Status::Success reply without data + /// `handler` is used to send back the reply. /// - returning a value other than CHIP_NO_ERROR implies an error reply (error and data are mutually exclusive) - /// - /// See InvokeReply/AutoCompleteInvokeResponder for details on how to send back replies and expected - /// error handling. If you need to know weather a response was successfully sent, use the underlying - /// `reply` object instead of returning an error code from Invoke. - /// - /// Return codes - /// CHIP_IM_GLOBAL_STATUS(code): - /// - error codes that are translatable to specific IM codes - /// - in particular, the following codes are interesting/expected - /// - `UnsupportedEndpoint` for invalid endpoint - /// - `UnsupportedCluster` for no such cluster on the endpoint - /// - `UnsupportedCommand` for no such command in the cluster - /// - `UnsupportedAccess` for permission errors (ACL or fabric scoped with invalid fabric) - /// - `NeedsTimedInteraction` if the invoke requires timed interaction support - virtual CHIP_ERROR Invoke(const InvokeRequest & request, chip::TLV::TLVReader & input_arguments, InvokeReply & reply) = 0; + virtual CHIP_ERROR Invoke(const InvokeRequest & request, chip::TLV::TLVReader & input_arguments, CommandHandler * handler) = 0; private: InteractionModelContext mContext = { nullptr }; diff --git a/src/app/data-model-interface/InvokeResponder.h b/src/app/data-model-interface/InvokeResponder.h deleted file mode 100644 index 9890c3bb6f6d7e..00000000000000 --- a/src/app/data-model-interface/InvokeResponder.h +++ /dev/null @@ -1,316 +0,0 @@ -/* - * 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 { -namespace InteractionModel { - -/// Handles encoding of an invoke response for a specific invoke request. -/// -/// This class handles a single request (i.e. a CommandDataIB within the -/// matter protocol) and is responsible for constructing its corresponding -/// response (i.e. a InvokeResponseIB within the matter protocol) -/// -/// Invoke responses MUST contain exactly ONE of: -/// - response data (accessed via `ResponseEncoder`) -/// - A status, which may be success or failure, both of which may -/// contain a cluster-specific error code. -/// -/// To encode a response, `Complete` MUST be called. -/// -/// `Complete` requirements -/// - Complete with InteractionModel::Status::Success will respond with data -/// some response data was written. -/// - Any other case (including success with cluster specific codes) implies -/// no response data and a status will be encoded instead -/// - this includes the case when some response data was written already. -/// In that case, the response data will be rolled back and only the status -/// will be encoded. -/// -/// Creating a response MAY be retried at most once, if and only if `Complete` -/// returns CHIP_ERROR_BUFFER_TOO_SMALL. Retry attempts MUST not exceed 1: -/// - FlushPendingResponses MUST be called to make as much buffer space as possible -/// available for encoding -/// - The response encoding (including `ResponseEncoder` usage and calling Complete) -/// MUST be retried once more. If the final Complete returns an error, the result -/// of the invoke will be an error status. -/// -class InvokeResponder -{ -public: - virtual ~InvokeResponder() = default; - - // Copying not allowed since underlying requirement is that on deletion of this - // object, a reply will be sent. - InvokeResponder(const InvokeResponder &) = delete; - InvokeResponder & operator=(const InvokeResponder &) = delete; - - /// Flush any pending replies before encoding the current reply. - /// - /// MAY be called at most once. - /// - /// This function is intended to provided the ability to retry sending a reply - /// if a reply encoding fails due to insufficient buffer. - /// - /// Call this if `Complete(...)` returns CHIP_ERROR_BUFFER_TOO_SMALL and try - /// again. If reply data is needed, the complete ResponseEncoder + Complete - /// call chain MUST be re-run. - virtual CHIP_ERROR FlushPendingResponses() = 0; - - /// Reply with a data payload. - /// - /// MUST be called at most once per reply. - /// Can be called a 2nd time after a `FlushPendingResponses()` call - /// - /// - responseCommandId must correspond with the data encoded in the returned encoder - /// - Complete(CHIP_NO_ERROR) MUST be called to flush the reply - /// - /// If encoder returns CHIP_ERROR_BUFFER_TOO_SMALL, FlushPendingResponses should be - /// used to attempt to free up buffer space then encoding should be tried again. - virtual DataModel::WrappedStructEncoder & ResponseEncoder(CommandId responseCommandId) = 0; - - /// Signal completing of the reply. - /// - /// MUST be called exactly once to signal a response is to be recorded to be sent. - /// The error code (and the data encoded by ResponseEncoder) may be buffered for - /// sending among other batched responses. - /// - /// If this returns CHIP_ERROR_BUFFER_TOO_SMALL, this can be called a 2nd time after - /// a FlushPendingResponses. - /// - /// Argument behavior: - /// - Commands can only be replied with ONE of the following (spec 8.9.4.4): - /// - command data (i.e. ResponseEncoder contents) - /// - A status (including success/error/cluster-specific-success-or-error ) - /// - As a result there are two possible paths: - /// - IF a Status::Success is given (WITHOUT cluster specific status), then - /// the data in ResponseEncoder is sent as a reply. If no data was sent, - /// a invoke `Status::Success` with no cluster specific data is sent - /// - OTHERWISE any previously encoded data via ResponseEncoder is discarded - /// and the given reply (success with cluster status or failure) is sent - /// as a reply to the invoke. - /// - /// - /// Returns success/failure state. One error code MUST be handled in particular: - /// - /// - CHIP_ERROR_BUFFER_TOO_SMALL will return IF AND ONLY IF the responder was unable - /// to fully serialize the given reply/error data. - /// - /// If such an error is returned, the caller MUST retry by calling FlushPendingResponses - /// first and then re-encoding the reply content (use ResponseEncoder if applicable and - /// call Complete again) - /// - /// - Any other error (i.e. different from CHIP_NO_ERROR) mean that the invoke response - /// will contain an error and such an error is considered permanent. - /// - virtual CHIP_ERROR Complete(StatusIB error) = 0; -}; - -/// Enforces that once acquired, Complete will be called on the underlying writer -class AutoCompleteInvokeResponder -{ -public: - // non-copyable: once you have a handle, keep it - AutoCompleteInvokeResponder(const AutoCompleteInvokeResponder &) = delete; - AutoCompleteInvokeResponder & operator=(const AutoCompleteInvokeResponder &) = delete; - - AutoCompleteInvokeResponder(InvokeResponder * writer) : mWriter(writer) {} - ~AutoCompleteInvokeResponder() - { - if (mCompleteState != CompleteState::kComplete) - { - mWriter->Complete(StatusIB{ Protocols::InteractionModel::Status::Failure }); - } - } - - /// Direct access to reply encoding. - /// - /// Use this only in conjunction with the other Raw* calls - DataModel::WrappedStructEncoder & RawResponseEncoder(CommandId replyCommandId) - { - return mWriter->ResponseEncoder(replyCommandId); - } - - /// Direct access to flushing replies - /// - /// Use this only in conjunction with the other Raw* calls - CHIP_ERROR RawFlushPendingReplies() - { - // allow a flush if we never called it (this may not be reasonable, however - // we accept an early flush) or if flush is expected - VerifyOrReturnError((mCompleteState == CompleteState::kNeverCalled) || (mCompleteState == CompleteState::kFlushExpected), - CHIP_ERROR_INCORRECT_STATE); - mCompleteState = CompleteState::kFlushed; - return mWriter->FlushPendingResponses(); - } - - /// Call "Complete" without the automatic retries. - /// - /// Use this in conjunction with the other Raw* calls - CHIP_ERROR RawComplete(StatusIB status) - { - VerifyOrReturnError((mCompleteState == CompleteState::kNeverCalled) || (mCompleteState == CompleteState::kFlushed), - CHIP_ERROR_INCORRECT_STATE); - CHIP_ERROR err = mWriter->Complete(status); - if ((err == CHIP_ERROR_BUFFER_TOO_SMALL) && (mCompleteState == CompleteState::kNeverCalled)) - { - mCompleteState = CompleteState::kFlushExpected; - } - else - { - mCompleteState = CompleteState::kComplete; - } - return err; - } - - /// Complete the given command. - /// - /// Automatically handles retries for sending. - /// Cannot be called after Raw* methods are used. - /// - /// Any error returned by this are final and not retriable - /// as a retry for CHIP_ERROR_BUFFER_TOO_SMALL is already built in. - CHIP_ERROR Complete(StatusIB status) - { - VerifyOrReturnError(mCompleteState == CompleteState::kNeverCalled, CHIP_ERROR_INCORRECT_STATE); - // this is a final complete, including retry handling - mCompleteState = CompleteState::kComplete; - CHIP_ERROR err = mWriter->Complete(status); - - if (err != CHIP_ERROR_BUFFER_TOO_SMALL) - { - return err; - } - - // retry once. Failure to flush is permanent. - ReturnErrorOnFailure(mWriter->FlushPendingResponses()); - return mWriter->Complete(status); - } - - /// Sends the specified data structure as a response - /// - /// This version of the send has built-in RETRY and handles - /// Flush/Complete automatically. - /// Cannot be called after Raw* methods are used. - /// - /// Any error returned by this are final and not retriable - /// as a retry for CHIP_ERROR_BUFFER_TOO_SMALL is already built in. - template - CHIP_ERROR Send(const ReplyData & data) - { - VerifyOrReturnError(mCompleteState == CompleteState::kNeverCalled, CHIP_ERROR_INCORRECT_STATE); - // this is a final complete, including retry handling - mCompleteState = CompleteState::kComplete; - CHIP_ERROR err = data.Encode(ResponseEncoder(ReplyData::GetCommandId())); - if (err != CHIP_ERROR_BUFFER_TOO_SMALL) - { - LogErrorOnFailure(err); - err = mWriter->Complete(StatusIB(err)); - } - if (err != CHIP_ERROR_BUFFER_TOO_SMALL) - { - return err; - } - - // retry once. Failure to flush is permanent. - ReturnErrorOnFailure(mWriter->FlushPendingResponses()); - err = data.Encode(ResponseEncoder(ReplyData::GetCommandId())); - - // If encoding fails, we will end up sending an error back to the other side - // the caller - LogErrorOnFailure(err); - if (err == CHIP_NO_ERROR) - { - err = mWriter->Complete(StatusIB(err)); - } - else - { - // Error in "complete" is not something we can really forward anymore since - // we already got an error in Encode ... just log this. - LogErrorOnFailure(mWriter->Complete(StatusIB(err))); - } - - return err; - } - -private: - // Contract says that complete may only be called twice: - // - initial complete - // - again after a `Flush` - // The states here expect we are in: - // - // +----------------------------Flush---------| - // | v - // NEVER --Complete--> F_EXPECTED --Flush--> FLUSHED --Complete--> COMPLETE - // | ^ - // +-------------(success or permanent error)-----------| - enum class CompleteState - { - kNeverCalled, - kFlushExpected, - kFlushed, - kComplete, - }; - - InvokeResponder * mWriter; - CompleteState mCompleteState = CompleteState::kNeverCalled; -}; - -enum ReplyAsyncFlags -{ - // Some commands that are expensive to process (e.g. crypto). - // Implementations may choose to send an ack on the message right away to - // avoid MRP retransmits. - kSlowCommandHandling = 0x0001, -}; - -class InvokeReply -{ -public: - virtual ~InvokeReply() = default; - - // reply with no data - CHIP_ERROR Reply(StatusIB status) { return this->Reply().Complete(status); } - - // Enqueue the content of the reply at this point in time (rather than Async sending it). - // - // Implementations will often batch several replies into one packet for batch commands, - // so it will be implementation-specific on when the actual reply packet is - // sent. - virtual AutoCompleteInvokeResponder Reply() = 0; - - // Reply "later" to the command. This allows async processing. A reply will be forced - // when the returned InvokeReply is destroyed. - // - // NOTE: Each InvokeReply is associated with a separate `CommandDataIB` within batch - // commands. When replying asynchronously, each InvokeReply will set the response - // data for the given commandpath/ref only. - // - // IF empty pointer is returned, insufficient memory to reply async is available and - // this should be handled (e.g. by returning an error to the handler/replying with - // an errorcode synchronously). - virtual std::unique_ptr ReplyAsync(BitFlags flags) = 0; -}; - -} // namespace InteractionModel -} // namespace app -} // namespace chip diff --git a/src/app/icd/server/tests/TestICDManager.cpp b/src/app/icd/server/tests/TestICDManager.cpp index 0b3c1a459441dd..83d3b1fd9951c1 100644 --- a/src/app/icd/server/tests/TestICDManager.cpp +++ b/src/app/icd/server/tests/TestICDManager.cpp @@ -15,6 +15,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include + #include #include #include @@ -24,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -124,18 +125,16 @@ class TestSubscriptionsInfoProvider : public SubscriptionsInfoProvider bool mHasPersistedSubscription = false; }; -System::Clock::Internal::MockClock * pMockClock = nullptr; -System::Clock::ClockBase * pRealClock = nullptr; -chip::Test::LoopbackMessagingContext * pMessagingContext = nullptr; +System::Clock::Internal::MockClock * pMockClock = nullptr; +System::Clock::ClockBase * pRealClock = nullptr; } // namespace namespace chip { namespace app { -class TestICDManager : public ::testing::Test +class TestICDManager : public Test::LoopbackMessagingContext { - public: /* * Advance the test Mock clock time by the amout passed in argument @@ -147,7 +146,7 @@ class TestICDManager : public ::testing::Test static void AdvanceClockAndRunEventLoop(Milliseconds64 time) { pMockClock->AdvanceMonotonic(time); - pMessagingContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); } // Performs shared setup for all tests in the test suite @@ -159,16 +158,12 @@ class TestICDManager : public ::testing::Test ASSERT_NE(pMockClock, nullptr); } - if (pMessagingContext == nullptr) - { - pMessagingContext = new LoopbackMessagingContext(); - ASSERT_NE(pMessagingContext, nullptr); - } + LoopbackMessagingContext::SetUpTestSuite(); + VerifyOrReturn(!HasFailure()); - pMessagingContext->SetUpTestSuite(); ASSERT_EQ(chip::DeviceLayer::PlatformMgr().InitChipStack(), CHIP_NO_ERROR); - DeviceLayer::SetSystemLayerForTesting(&(pMessagingContext->GetSystemLayer())); + DeviceLayer::SetSystemLayerForTesting(&GetSystemLayer()); pRealClock = &SystemClock(); Clock::Internal::SetSystemClockForTesting(pMockClock); } @@ -180,7 +175,8 @@ class TestICDManager : public ::testing::Test DeviceLayer::SetSystemLayerForTesting(nullptr); DeviceLayer::PlatformMgr().Shutdown(); - pMessagingContext->TearDownTestSuite(); + + LoopbackMessagingContext::TearDownTestSuite(); if (pMockClock != nullptr) { @@ -188,31 +184,25 @@ class TestICDManager : public ::testing::Test pMockClock = nullptr; } - if (pMessagingContext != nullptr) - { - delete pMessagingContext; - pMessagingContext = nullptr; - } - pRealClock = nullptr; } // Performs setup for each individual test in the test suite void SetUp() override { - pMessagingContext->SetUp(); + LoopbackMessagingContext::SetUp(); + VerifyOrReturn(!HasFailure()); mICDStateObserver.ResetAll(); mICDManager.RegisterObserver(&mICDStateObserver); - mICDManager.Init(&testStorage, &(pMessagingContext->GetFabricTable()), &mKeystore, - &(pMessagingContext->GetExchangeManager()), &mSubInfoProvider); + mICDManager.Init(&testStorage, &GetFabricTable(), &mKeystore, &GetExchangeManager(), &mSubInfoProvider); } // Performs teardown for each individual test in the test suite void TearDown() override { mICDManager.Shutdown(); - pMessagingContext->TearDown(); + LoopbackMessagingContext::TearDown(); } TestSessionKeystoreImpl mKeystore; @@ -576,8 +566,7 @@ TEST_F(TestICDManager, TestICDCounter) // Shut down and reinit ICDManager to increment counter mICDManager.Shutdown(); - mICDManager.Init(&(testStorage), &(pMessagingContext->GetFabricTable()), &(mKeystore), - &(pMessagingContext->GetExchangeManager()), &(mSubInfoProvider)); + mICDManager.Init(&(testStorage), &GetFabricTable(), &(mKeystore), &GetExchangeManager(), &(mSubInfoProvider)); mICDManager.RegisterObserver(&(mICDStateObserver)); EXPECT_EQ(counter + ICDConfigurationData::kICDCounterPersistenceIncrement, @@ -982,8 +971,7 @@ TEST_F(TestICDManager, TestICDStateObserverOnICDModeChangeOnInit) // Shut down and reinit ICDManager - We should go to LIT mode since we have a registration mICDManager.Shutdown(); mICDManager.RegisterObserver(&(mICDStateObserver)); - mICDManager.Init(&testStorage, &(pMessagingContext->GetFabricTable()), &mKeystore, &(pMessagingContext->GetExchangeManager()), - &mSubInfoProvider); + mICDManager.Init(&testStorage, &GetFabricTable(), &mKeystore, &GetExchangeManager(), &mSubInfoProvider); // We have a registration, transition to LIT mode EXPECT_TRUE(mICDStateObserver.mOnICDModeChangeCalled); diff --git a/src/app/tests/AppTestContext.cpp b/src/app/tests/AppTestContext.cpp index ff1154dafbb306..ecf4aff9bf7c40 100644 --- a/src/app/tests/AppTestContext.cpp +++ b/src/app/tests/AppTestContext.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include +#include "AppTestContext.h" #include #include @@ -40,11 +40,10 @@ namespace Test { void AppContext::SetUpTestSuite() { - CHIP_ERROR err = CHIP_NO_ERROR; LoopbackMessagingContext::SetUpTestSuite(); - // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete - VerifyOrDieWithMsg((err = chip::DeviceLayer::PlatformMgr().InitChipStack()) == CHIP_NO_ERROR, AppServer, - "Init CHIP stack failed: %" CHIP_ERROR_FORMAT, err.Format()); + VerifyOrReturn(!HasFailure()); // Stop if parent had a failure. + + ASSERT_EQ(chip::DeviceLayer::PlatformMgr().InitChipStack(), CHIP_NO_ERROR); } void AppContext::TearDownTestSuite() @@ -67,17 +66,15 @@ void AppContext::TearDownTestSuite() void AppContext::SetUp() { - CHIP_ERROR err = CHIP_NO_ERROR; LoopbackMessagingContext::SetUp(); - // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete - VerifyOrDieWithMsg((err = app::InteractionModelEngine::GetInstance()->Init(&GetExchangeManager(), &GetFabricTable(), - app::reporting::GetDefaultReportScheduler())) == - CHIP_NO_ERROR, - AppServer, "Init InteractionModelEngine failed: %" CHIP_ERROR_FORMAT, err.Format()); + VerifyOrReturn(!HasFailure()); // Stop if parent had a failure. + + ASSERT_EQ(app::InteractionModelEngine::GetInstance()->Init(&GetExchangeManager(), &GetFabricTable(), + app::reporting::GetDefaultReportScheduler()), + CHIP_NO_ERROR); Access::SetAccessControl(gPermissiveAccessControl); - VerifyOrDieWithMsg((err = Access::GetAccessControl().Init(chip::Access::Examples::GetPermissiveAccessControlDelegate(), - gDeviceTypeResolver)) == CHIP_NO_ERROR, - AppServer, "Init AccessControl failed: %" CHIP_ERROR_FORMAT, err.Format()); + ASSERT_EQ(Access::GetAccessControl().Init(chip::Access::Examples::GetPermissiveAccessControlDelegate(), gDeviceTypeResolver), + CHIP_NO_ERROR); } void AppContext::TearDown() @@ -85,6 +82,7 @@ void AppContext::TearDown() Access::GetAccessControl().Finish(); Access::ResetAccessControlToDefault(); chip::app::InteractionModelEngine::GetInstance()->Shutdown(); + LoopbackMessagingContext::TearDown(); } diff --git a/src/app/tests/AppTestContext.h b/src/app/tests/AppTestContext.h index a2fe3387d2d7aa..c05e490fb9e6aa 100644 --- a/src/app/tests/AppTestContext.h +++ b/src/app/tests/AppTestContext.h @@ -32,9 +32,9 @@ class AppContext : public LoopbackMessagingContext // Performs shared teardown for all tests in the test suite static void TearDownTestSuite(); // Performs setup for each individual test in the test suite - void SetUp(); + virtual void SetUp(); // Performs teardown for each individual test in the test suite - void TearDown(); + virtual void TearDown(); }; } // namespace Test diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn index 1dc973dc98a93a..c1826884923af4 100644 --- a/src/app/tests/BUILD.gn +++ b/src/app/tests/BUILD.gn @@ -40,7 +40,10 @@ static_library("helpers") { "${chip_root}/src/transport/raw/tests:helpers", ] - public_deps = [ "${chip_root}/src/messaging/tests:helpers" ] + public_deps = [ + "${chip_root}/src/lib/support/tests:pw-test-macros", + "${chip_root}/src/messaging/tests:helpers", + ] } source_set("binding-test-srcs") { diff --git a/src/app/tests/TestAclAttribute.cpp b/src/app/tests/TestAclAttribute.cpp index 8ff88967deb5b0..fac82e484d7450 100644 --- a/src/app/tests/TestAclAttribute.cpp +++ b/src/app/tests/TestAclAttribute.cpp @@ -109,50 +109,31 @@ class MockInteractionModelApp : public chip::app::ReadClient::Callback namespace chip { namespace app { -class TestAclAttribute : public ::testing::Test +class TestAclAttribute : public Test::AppContext { public: - static void SetUpTestSuite() - { - - mpTestContext = new chip::Test::AppContext; - mpTestContext->SetUpTestSuite(); - } - static void TearDownTestSuite() - { - mpTestContext->TearDownTestSuite(); - delete mpTestContext; - } - void SetUp() override { - mpTestContext->SetUp(); + AppContext::SetUp(); Access::GetAccessControl().Finish(); Access::GetAccessControl().Init(GetTestAccessControlDelegate(), gDeviceTypeResolver); } - void TearDown() override { mpTestContext->TearDown(); } - - static chip::Test::AppContext * mpTestContext; }; -chip::Test::AppContext * TestAclAttribute::mpTestContext = nullptr; - // Read Client sends a malformed subscribe request, interaction model engine fails to parse the request and generates a status // report to client, and client is closed. TEST_F(TestAclAttribute, TestACLDeniedAttribute) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler()), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); chip::app::AttributePathParams attributePathParams[2]; @@ -164,13 +145,13 @@ TEST_F(TestAclAttribute, TestACLDeniedAttribute) attributePathParams[1].mClusterId = chip::Test::kTestDeniedClusterId1; attributePathParams[1].mAttributeId = 2; - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mAttributePathParamsListSize = 2; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mError, CHIP_IM_GLOBAL_STATUS(InvalidAction)); EXPECT_FALSE(delegate.mGotReport); delegate.mError = CHIP_NO_ERROR; @@ -178,7 +159,7 @@ TEST_F(TestAclAttribute, TestACLDeniedAttribute) } { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); chip::app::AttributePathParams attributePathParams[2]; @@ -189,13 +170,13 @@ TEST_F(TestAclAttribute, TestACLDeniedAttribute) attributePathParams[1].mClusterId = chip::Test::kTestDeniedClusterId2; attributePathParams[1].mAttributeId = 2; - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mAttributePathParamsListSize = 2; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mError, CHIP_IM_GLOBAL_STATUS(InvalidAction)); EXPECT_FALSE(delegate.mGotReport); delegate.mError = CHIP_NO_ERROR; @@ -203,7 +184,7 @@ TEST_F(TestAclAttribute, TestACLDeniedAttribute) } { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); chip::app::AttributePathParams attributePathParams[2]; @@ -215,13 +196,13 @@ TEST_F(TestAclAttribute, TestACLDeniedAttribute) attributePathParams[1].mClusterId = chip::Test::kTestClusterId; attributePathParams[1].mAttributeId = 2; - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mAttributePathParamsListSize = 2; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mError, CHIP_NO_ERROR); EXPECT_TRUE(delegate.mGotReport); EXPECT_EQ(engine->GetNumActiveReadHandlers(ReadHandler::InteractionType::Subscribe), 1u); @@ -231,7 +212,7 @@ TEST_F(TestAclAttribute, TestACLDeniedAttribute) EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } } // namespace app } // namespace chip diff --git a/src/app/tests/TestAclEvent.cpp b/src/app/tests/TestAclEvent.cpp index 014625ad628b65..c216e8d1f9565d 100644 --- a/src/app/tests/TestAclEvent.cpp +++ b/src/app/tests/TestAclEvent.cpp @@ -172,21 +172,9 @@ class MockInteractionModelApp : public chip::app::ReadClient::Callback namespace chip { namespace app { -class TestAclEvent : public ::testing::Test +class TestAclEvent : public Test::AppContext { public: - static void SetUpTestSuite() - { - - mpTestContext = new chip::Test::AppContext; - mpTestContext->SetUpTestSuite(); - } - static void TearDownTestSuite() - { - mpTestContext->TearDownTestSuite(); - delete mpTestContext; - } - // Performs setup for each individual test in the test suite void SetUp() override { @@ -196,10 +184,10 @@ class TestAclEvent : public ::testing::Test { &gCritEventBuffer[0], sizeof(gCritEventBuffer), chip::app::PriorityLevel::Critical }, }; - mpTestContext->SetUp(); + AppContext::SetUp(); ASSERT_EQ(mEventCounter.Init(0), CHIP_NO_ERROR); - chip::app::EventManagement::CreateEventManagement(&mpTestContext->GetExchangeManager(), ArraySize(logStorageResources), + chip::app::EventManagement::CreateEventManagement(&GetExchangeManager(), ArraySize(logStorageResources), gCircularEventBuffer, logStorageResources, &mEventCounter); Access::GetAccessControl().Finish(); @@ -210,21 +198,17 @@ class TestAclEvent : public ::testing::Test void TearDown() override { chip::app::EventManagement::DestroyEventManagement(); - mpTestContext->TearDown(); + AppContext::TearDown(); } - static chip::Test::AppContext * mpTestContext; - private: chip::MonotonicallyIncreasingCounter mEventCounter; }; -chip::Test::AppContext * TestAclEvent::mpTestContext = nullptr; - TEST_F(TestAclEvent, TestReadRoundtripWithEventStatusIBInEventReport) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_FALSE(rm->TestGetCountRetransTable()); @@ -232,9 +216,7 @@ TEST_F(TestAclEvent, TestReadRoundtripWithEventStatusIBInEventReport) auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler()), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); // A custom AccessControl::Delegate has been installed that grants privilege to any cluster except the test cluster. // When reading events with concrete paths without enough privilege, we will get a EventStatusIB @@ -244,7 +226,7 @@ TEST_F(TestAclEvent, TestReadRoundtripWithEventStatusIBInEventReport) eventPathParams[0].mClusterId = chip::Test::kTestDeniedClusterId2; eventPathParams[0].mEventId = kTestEventIdDebug; - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpEventPathParamsList = eventPathParams; readPrepareParams.mEventPathParamsListSize = 1; readPrepareParams.mEventNumber.SetValue(1); @@ -252,12 +234,12 @@ TEST_F(TestAclEvent, TestReadRoundtripWithEventStatusIBInEventReport) MockInteractionModelApp delegate; EXPECT_FALSE(delegate.mGotEventResponse); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotEventResponse); EXPECT_TRUE(delegate.mNumReadEventFailureStatusReceived); @@ -274,7 +256,7 @@ TEST_F(TestAclEvent, TestReadRoundtripWithEventStatusIBInEventReport) eventPathParams[0].mEndpointId = kTestEndpointId; eventPathParams[0].mClusterId = chip::Test::kTestDeniedClusterId2; - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpEventPathParamsList = eventPathParams; readPrepareParams.mEventPathParamsListSize = 1; readPrepareParams.mEventNumber.SetValue(1); @@ -282,12 +264,12 @@ TEST_F(TestAclEvent, TestReadRoundtripWithEventStatusIBInEventReport) MockInteractionModelApp delegate; EXPECT_FALSE(delegate.mGotEventResponse); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_FALSE(delegate.mGotEventResponse); EXPECT_FALSE(delegate.mNumReadEventFailureStatusReceived); EXPECT_FALSE(delegate.mReadError); @@ -301,7 +283,7 @@ TEST_F(TestAclEvent, TestReadRoundtripWithEventStatusIBInEventReport) chip::app::EventPathParams eventPathParams[1]; eventPathParams[0].mEndpointId = kTestEndpointId; - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpEventPathParamsList = eventPathParams; readPrepareParams.mEventPathParamsListSize = 1; readPrepareParams.mEventNumber.SetValue(1); @@ -309,12 +291,12 @@ TEST_F(TestAclEvent, TestReadRoundtripWithEventStatusIBInEventReport) MockInteractionModelApp delegate; EXPECT_FALSE(delegate.mGotEventResponse); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotEventResponse); EXPECT_FALSE(delegate.mNumReadEventFailureStatusReceived); EXPECT_FALSE(delegate.mReadError); @@ -333,7 +315,7 @@ TEST_F(TestAclEvent, TestReadRoundtripWithEventStatusIBInEventReport) eventPathParams[1].mClusterId = kTestClusterId2; eventPathParams[1].mEventId = kTestEventIdCritical; - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpEventPathParamsList = eventPathParams; readPrepareParams.mEventPathParamsListSize = 1; readPrepareParams.mEventNumber.SetValue(1); @@ -341,19 +323,19 @@ TEST_F(TestAclEvent, TestReadRoundtripWithEventStatusIBInEventReport) MockInteractionModelApp delegate; EXPECT_FALSE(delegate.mGotEventResponse); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotEventResponse); EXPECT_TRUE(delegate.mNumReadEventFailureStatusReceived); EXPECT_FALSE(delegate.mReadError); } EXPECT_FALSE(engine->GetNumActiveReadClients()); engine->Shutdown(); - EXPECT_FALSE(mpTestContext->GetExchangeManager().GetNumActiveExchanges()); + EXPECT_FALSE(GetExchangeManager().GetNumActiveExchanges()); } } // namespace app diff --git a/src/app/tests/TestBufferedReadCallback.cpp b/src/app/tests/TestBufferedReadCallback.cpp index 91836675db25f4..f3afeb7715cee3 100644 --- a/src/app/tests/TestBufferedReadCallback.cpp +++ b/src/app/tests/TestBufferedReadCallback.cpp @@ -31,7 +31,6 @@ #include #include -using TestContext = chip::Test::AppContext; using namespace chip::app; using namespace chip; @@ -65,39 +64,7 @@ struct ValidationInstruction using InstructionListType = std::vector; -class TestBufferedReadCallback : public ::testing::Test -{ -public: - static void SetUpTestSuite() - { - mpTestContext = new TestContext; - mpTestContext->SetUpTestSuite(); - } - static void TearDownTestSuite() - { - mpTestContext->TearDownTestSuite(); - if (mpTestContext != nullptr) - { - delete mpTestContext; - } - } - void SetUp() override - { - if (mpTestContext != nullptr) - { - mpTestContext->SetUp(); - } - } - void TearDown() override - { - if (mpTestContext != nullptr) - { - mpTestContext->TearDown(); - } - } - static TestContext * mpTestContext; -}; -TestContext * TestBufferedReadCallback::mpTestContext = nullptr; +using TestBufferedReadCallback = chip::Test::AppContext; class DataSeriesValidator : public BufferedReadCallback::Callback { @@ -268,11 +235,11 @@ void DataSeriesValidator::OnAttributeData(const ConcreteDataAttributePath & aPat auto iter = value.begin(); - uint8_t index = 0; + uint32_t index = 0; while (iter.Next() && index < expectedListLength) { auto & iterValue = iter.GetValue(); - EXPECT_EQ(iterValue, (index)); + EXPECT_EQ(iterValue, (index % 256)); index++; } diff --git a/src/app/tests/TestClusterStateCache.cpp b/src/app/tests/TestClusterStateCache.cpp index 782c8f07f87347..972d85d4df9e2a 100644 --- a/src/app/tests/TestClusterStateCache.cpp +++ b/src/app/tests/TestClusterStateCache.cpp @@ -37,7 +37,6 @@ #include #include -using TestContext = chip::Test::AppContext; using namespace chip::app; using namespace chip; @@ -113,26 +112,7 @@ uint8_t AttributeInstruction::sInstructionId = 0; using AttributeInstructionListType = std::vector; -class TestClusterStateCache : public ::testing::Test -{ -public: - static void SetUpTestSuite() - { - mpTestContext = new TestContext; - mpTestContext->SetUpTestSuite(); - } - static void TearDownTestSuite() - { - mpTestContext->TearDownTestSuite(); - delete mpTestContext; - } - - void SetUp() override { mpTestContext->SetUp(); } - void TearDown() override { mpTestContext->TearDown(); } - - static TestContext * mpTestContext; -}; -TestContext * TestClusterStateCache::mpTestContext = nullptr; +using TestClusterStateCache = chip::Test::AppContext; class ForwardedDataCallbackValidator final { diff --git a/src/app/tests/TestCommandInteraction.cpp b/src/app/tests/TestCommandInteraction.cpp index 8c2537a925e9b1..6212d696c85c45 100644 --- a/src/app/tests/TestCommandInteraction.cpp +++ b/src/app/tests/TestCommandInteraction.cpp @@ -50,7 +50,6 @@ #include #include -using TestContext = chip::Test::AppContext; using namespace chip::Protocols; namespace { @@ -357,25 +356,9 @@ class MockCommandHandlerCallback : public CommandHandlerImpl::Callback int onFinalCalledTimes = 0; } mockCommandHandlerDelegate; -class TestCommandInteraction : public ::testing::Test +class TestCommandInteraction : public chip::Test::AppContext { public: - static void SetUpTestSuite() - { - mpTestContext = new TestContext; - mpTestContext->SetUpTestSuite(); - } - static void TearDownTestSuite() - { - mpTestContext->TearDownTestSuite(); - delete mpTestContext; - } - - void SetUp() override { mpTestContext->SetUp(); } - void TearDown() override { mpTestContext->TearDown(); } - - static TestContext * mpTestContext; - static size_t GetNumActiveCommandResponderObjects() { return chip::app::InteractionModelEngine::GetInstance()->mCommandResponderObjs.Allocated(); @@ -443,7 +426,6 @@ class TestCommandInteraction : public ::testing::Test const ConcreteCommandPath & aRequestCommandPath, uint32_t aSizeToLeaveInBuffer); static void ValidateCommandHandlerEncodeInvokeResponseMessage(bool aNeedStatusCode); }; -TestContext * TestCommandInteraction::mpTestContext = nullptr; class TestExchangeDelegate : public Messaging::ExchangeDelegate { @@ -686,19 +668,19 @@ void TestCommandInteraction::ValidateCommandHandlerEncodeInvokeResponseMessage(b TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage1) { mockCommandSenderDelegate.ResetCounter(); - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); AddInvokeRequestData(&commandSender); asyncCommand = false; - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 1; - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 1; + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); + DrainAndServiceIO(); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0); EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 0); @@ -718,19 +700,19 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage1) PayloadHeader payloadHeader; payloadHeader.SetExchangeID(0); payloadHeader.SetMessageType(chip::Protocols::InteractionModel::MsgType::StatusResponse); - chip::Test::MessageCapturer messageLog(*mpTestContext); + chip::Test::MessageCapturer messageLog(*this); messageLog.mCaptureStandaloneAcks = false; // Since we are dropping packets, things are not getting acked. Set up our // MRP state to look like what it would have looked like if the packet had // not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, commandSender.mExchangeCtx.Get()); + PretendWeGotReplyFromServer(*this, commandSender.mExchangeCtx.Get()); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(commandSender.OnMessageReceived(commandSender.mExchangeCtx.Get(), payloadHeader, std::move(msgBuf)), CHIP_IM_GLOBAL_STATUS(Busy)); @@ -740,16 +722,16 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage1) EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 1); EXPECT_EQ(commandSender.GetInvokeResponseMessageCount(), 0u); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Client sent status report with invalid action, server's exchange has been closed, so all it sent is an MRP Ack - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); CheckForInvalidAction(messageLog); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // Command Sender sends invoke request, command handler drops invoke response, then test injects unknown message to client, @@ -757,19 +739,19 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage1) TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage2) { mockCommandSenderDelegate.ResetCounter(); - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); AddInvokeRequestData(&commandSender); asyncCommand = false; - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 1; - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 1; + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); + DrainAndServiceIO(); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0); EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 0); @@ -788,19 +770,19 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage2) PayloadHeader payloadHeader; payloadHeader.SetExchangeID(0); payloadHeader.SetMessageType(chip::Protocols::InteractionModel::MsgType::ReportData); - chip::Test::MessageCapturer messageLog(*mpTestContext); + chip::Test::MessageCapturer messageLog(*this); messageLog.mCaptureStandaloneAcks = false; // Since we are dropping packets, things are not getting acked. Set up our // MRP state to look like what it would have looked like if the packet had // not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, commandSender.mExchangeCtx.Get()); + PretendWeGotReplyFromServer(*this, commandSender.mExchangeCtx.Get()); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(commandSender.OnMessageReceived(commandSender.mExchangeCtx.Get(), payloadHeader, std::move(msgBuf)), CHIP_ERROR_INVALID_MESSAGE_TYPE); @@ -809,16 +791,16 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage2) EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1); EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 1); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Client sent status report with invalid action, server's exchange has been closed, so all it sent is an MRP Ack - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); CheckForInvalidAction(messageLog); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // Command Sender sends invoke request, command handler drops invoke response, then test injects malformed invoke response @@ -826,19 +808,19 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage2) TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage3) { mockCommandSenderDelegate.ResetCounter(); - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); AddInvokeRequestData(&commandSender); asyncCommand = false; - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 1; - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 1; + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); + DrainAndServiceIO(); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0); EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 0); @@ -857,18 +839,18 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage3) PayloadHeader payloadHeader; payloadHeader.SetExchangeID(0); payloadHeader.SetMessageType(chip::Protocols::InteractionModel::MsgType::InvokeCommandResponse); - chip::Test::MessageCapturer messageLog(*mpTestContext); + chip::Test::MessageCapturer messageLog(*this); messageLog.mCaptureStandaloneAcks = false; // Since we are dropping packets, things are not getting acked. Set up our // MRP state to look like what it would have looked like if the packet had // not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, commandSender.mExchangeCtx.Get()); + PretendWeGotReplyFromServer(*this, commandSender.mExchangeCtx.Get()); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(commandSender.OnMessageReceived(commandSender.mExchangeCtx.Get(), payloadHeader, std::move(msgBuf)), CHIP_ERROR_END_OF_TLV); @@ -877,16 +859,16 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage3) EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1); EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 1); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Client sent status report with invalid action, server's exchange has been closed, so all it sent is an MRP Ack - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); CheckForInvalidAction(messageLog); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // Command Sender sends invoke request, command handler drops invoke response, then test injects malformed status response to @@ -894,19 +876,19 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage3) TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage4) { mockCommandSenderDelegate.ResetCounter(); - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); AddInvokeRequestData(&commandSender); asyncCommand = false; - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 1; - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 1; + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); + DrainAndServiceIO(); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0); EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 0); @@ -924,18 +906,18 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage4) PayloadHeader payloadHeader; payloadHeader.SetExchangeID(0); payloadHeader.SetMessageType(chip::Protocols::InteractionModel::MsgType::StatusResponse); - chip::Test::MessageCapturer messageLog(*mpTestContext); + chip::Test::MessageCapturer messageLog(*this); messageLog.mCaptureStandaloneAcks = false; // Since we are dropping packets, things are not getting acked. Set up our // MRP state to look like what it would have looked like if the packet had // not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, commandSender.mExchangeCtx.Get()); + PretendWeGotReplyFromServer(*this, commandSender.mExchangeCtx.Get()); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(commandSender.OnMessageReceived(commandSender.mExchangeCtx.Get(), payloadHeader, std::move(msgBuf)), CHIP_ERROR_END_OF_TLV); @@ -944,24 +926,24 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage4) EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1); EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 1); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Client sent status report with invalid action, server's exchange has been closed, so all it sent is an MRP Ack - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); CheckForInvalidAction(messageLog); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } TEST_F(TestCommandInteraction, TestCommandSender_WithWrongState) { - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_ERROR_INCORRECT_STATE); + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_ERROR_INCORRECT_STATE); } TEST_F(TestCommandInteraction, TestCommandHandler_WithWrongState) @@ -986,14 +968,14 @@ TEST_F(TestCommandInteraction, TestCommandHandler_WithWrongState) TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandSender_WithSendCommand) { - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); AddInvokeRequestData(&commandSender); - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); GenerateInvokeResponse(buf, kTestCommandIdWithData); bool moreChunkedMessages = false; @@ -1024,7 +1006,7 @@ TEST_F(TestCommandInteraction, TestCommandHandler_WithSendEmptyCommand) TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandSender_WithProcessReceivedMsg) { - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); @@ -1040,8 +1022,8 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandSender_ExtendableApiWithP mockCommandSenderExtendedDelegate.ResetCounter(); PendingResponseTrackerImpl pendingResponseTracker; - app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, - &mpTestContext->GetExchangeManager(), &pendingResponseTracker); + app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(), + &pendingResponseTracker); uint16_t mockCommandRef = 1; pendingResponseTracker.Add(mockCommandRef); @@ -1067,8 +1049,8 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandSender_ExtendableApiWithP mockCommandSenderExtendedDelegate.ResetCounter(); PendingResponseTrackerImpl pendingResponseTracker; - app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, - &mpTestContext->GetExchangeManager(), &pendingResponseTracker); + app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(), + &pendingResponseTracker); uint16_t mockCommandRef = 1; pendingResponseTracker.Add(mockCommandRef); @@ -1096,8 +1078,8 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandSender_ValidateSecondLarg { mockCommandSenderExtendedDelegate.ResetCounter(); PendingResponseTrackerImpl pendingResponseTracker; - app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, - &mpTestContext->GetExchangeManager(), &pendingResponseTracker); + app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(), + &pendingResponseTracker); app::CommandSender::AddRequestDataParameters addRequestDataParams; @@ -1123,10 +1105,10 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandSender_ValidateSecondLarg EXPECT_EQ(commandSender.AddRequestData(commandPathParams, requestData, addRequestDataParams), CHIP_ERROR_NO_MEMORY); // Confirm that we can still send out a request with the first command. - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); EXPECT_EQ(commandSender.GetInvokeResponseMessageCount(), 0u); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(mockCommandSenderExtendedDelegate.onResponseCalledTimes, 1); EXPECT_EQ(mockCommandSenderExtendedDelegate.onFinalCalledTimes, 1); @@ -1176,13 +1158,13 @@ TEST_F(TestCommandInteraction, TestCommandHandlerInvalidMessageSync) { mockCommandSenderDelegate.ResetCounter(); - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); chip::isCommandDispatched = false; AddInvalidInvokeRequestData(&commandSender); - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_FALSE(chip::isCommandDispatched); EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0); @@ -1190,7 +1172,7 @@ TEST_F(TestCommandInteraction, TestCommandHandlerInvalidMessageSync) EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 1); EXPECT_EQ(mockCommandSenderDelegate.mError, CHIP_IM_GLOBAL_STATUS(InvalidAction)); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommandInteraction, TestCommandHandlerCommandEncodeExternalFailure) @@ -1317,18 +1299,18 @@ TEST_F(TestCommandInteraction, TestCommandSenderLegacyCallbackUnsupportedCommand { mockCommandSenderDelegate.ResetCounter(); - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); AddInvokeRequestData(&commandSender, kTestNonExistCommandId); - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0); EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1); EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 1); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // Because UnsupportedCommand is a path specific error we will expect it to come via on response when using Extended Path. @@ -1336,25 +1318,25 @@ TEST_F(TestCommandInteraction, TestCommandSender_ExtendableCallbackUnsupportedCo { mockCommandSenderExtendedDelegate.ResetCounter(); - app::CommandSender commandSender(&mockCommandSenderExtendedDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderExtendedDelegate, &GetExchangeManager()); AddInvokeRequestData(&commandSender, kTestNonExistCommandId); - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(mockCommandSenderExtendedDelegate.onResponseCalledTimes, 1); EXPECT_EQ(mockCommandSenderExtendedDelegate.onFinalCalledTimes, 1); EXPECT_EQ(mockCommandSenderExtendedDelegate.onErrorCalledTimes, 0); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommandInteraction, TestCommandSenderLegacyCallbackBuildingBatchCommandFails) { mockCommandSenderDelegate.ResetCounter(); - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); app::CommandSender::PrepareCommandParameters prepareCommandParams; app::CommandSender::FinishCommandParameters finishCommandParams; prepareCommandParams.SetStartDataStruct(true).SetCommandRef(0); @@ -1376,15 +1358,15 @@ TEST_F(TestCommandInteraction, TestCommandSenderLegacyCallbackBuildingBatchComma EXPECT_EQ(commandSender.PrepareCommand(commandPathParams, prepareCommandParams), CHIP_ERROR_INCORRECT_STATE); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommandInteraction, TestCommandSender_ExtendableCallbackBuildingBatchDuplicateCommandRefFails) { mockCommandSenderExtendedDelegate.ResetCounter(); PendingResponseTrackerImpl pendingResponseTracker; - app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, - &mpTestContext->GetExchangeManager(), &pendingResponseTracker); + app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(), + &pendingResponseTracker); app::CommandSender::PrepareCommandParameters prepareCommandParams; app::CommandSender::FinishCommandParameters finishCommandParams; @@ -1404,15 +1386,15 @@ TEST_F(TestCommandInteraction, TestCommandSender_ExtendableCallbackBuildingBatch EXPECT_EQ(commandSender.PrepareCommand(commandPathParams, prepareCommandParams), CHIP_ERROR_INVALID_ARGUMENT); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommandInteraction, TestCommandSender_ExtendableCallbackBuildingBatchCommandSuccess) { mockCommandSenderExtendedDelegate.ResetCounter(); PendingResponseTrackerImpl pendingResponseTracker; - app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, - &mpTestContext->GetExchangeManager(), &pendingResponseTracker); + app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(), + &pendingResponseTracker); app::CommandSender::PrepareCommandParameters prepareCommandParams; app::CommandSender::FinishCommandParameters finishCommandParams; @@ -1440,20 +1422,20 @@ TEST_F(TestCommandInteraction, TestCommandSender_ExtendableCallbackBuildingBatch EXPECT_EQ(commandSender.FinishCommand(finishCommandParams), CHIP_NO_ERROR); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommandInteraction, TestCommandSenderCommandSuccessResponseFlow) { mockCommandSenderDelegate.ResetCounter(); - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); AddInvokeRequestData(&commandSender); - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); EXPECT_EQ(commandSender.GetInvokeResponseMessageCount(), 0u); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 1); EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1); @@ -1462,76 +1444,76 @@ TEST_F(TestCommandInteraction, TestCommandSenderCommandSuccessResponseFlow) EXPECT_EQ(commandSender.GetInvokeResponseMessageCount(), 1u); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommandInteraction, TestCommandSenderCommandAsyncSuccessResponseFlow) { mockCommandSenderDelegate.ResetCounter(); - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); AddInvokeRequestData(&commandSender); asyncCommand = true; - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0); EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 0); EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 1u); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 2u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 2u); // Decrease CommandHandler refcount and send response asyncCommandHandle = nullptr; - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 1); EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1); EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommandInteraction, TestCommandSenderCommandSpecificResponseFlow) { mockCommandSenderDelegate.ResetCounter(); - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); AddInvokeRequestData(&commandSender, kTestCommandIdCommandSpecificResponse); - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 1); EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1); EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommandInteraction, TestCommandSenderCommandFailureResponseFlow) { mockCommandSenderDelegate.ResetCounter(); - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); AddInvokeRequestData(&commandSender, kTestNonExistCommandId); - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0); EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1); EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 1); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommandInteraction, TestCommandSenderAbruptDestruction) @@ -1546,13 +1528,13 @@ TEST_F(TestCommandInteraction, TestCommandSenderAbruptDestruction) mockCommandSenderDelegate.ResetCounter(); { - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); AddInvokeRequestData(&commandSender, kTestCommandIdCommandSpecificResponse); - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // // No callbacks should be invoked yet - let's validate that. @@ -1561,13 +1543,13 @@ TEST_F(TestCommandInteraction, TestCommandSenderAbruptDestruction) EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 0); EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 1u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 1u); } // // Upon the sender being destructed by the application, our exchange should get cleaned up too. // - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); } @@ -1578,8 +1560,8 @@ TEST_F(TestCommandInteraction, TestCommandHandler_RejectMultipleIdenticalCommand isCommandDispatched = false; mockCommandSenderExtendedDelegate.ResetCounter(); PendingResponseTrackerImpl pendingResponseTracker; - app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, - &mpTestContext->GetExchangeManager(), &pendingResponseTracker); + app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(), + &pendingResponseTracker); app::CommandSender::ConfigParameters configParameters; configParameters.SetRemoteMaxPathsPerInvoke(2); @@ -1602,9 +1584,9 @@ TEST_F(TestCommandInteraction, TestCommandHandler_RejectMultipleIdenticalCommand EXPECT_EQ(CHIP_NO_ERROR, commandSender.FinishCommand(finishCommandParams)); } - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(mockCommandSenderExtendedDelegate.onResponseCalledTimes, 0); EXPECT_EQ(mockCommandSenderExtendedDelegate.onFinalCalledTimes, 1); @@ -1612,7 +1594,7 @@ TEST_F(TestCommandInteraction, TestCommandHandler_RejectMultipleIdenticalCommand EXPECT_FALSE(chip::isCommandDispatched); EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } #if CONFIG_BUILD_FOR_HOST_UNIT_TEST @@ -1623,8 +1605,8 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_RejectsMultipleCo isCommandDispatched = false; mockCommandSenderExtendedDelegate.ResetCounter(); PendingResponseTrackerImpl pendingResponseTracker; - app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, - &mpTestContext->GetExchangeManager(), &pendingResponseTracker); + app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(), + &pendingResponseTracker); app::CommandSender::ConfigParameters configParameters; configParameters.SetRemoteMaxPathsPerInvoke(2); @@ -1683,8 +1665,8 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_RejectMultipleCom mockCommandSenderExtendedDelegate.ResetCounter(); PendingResponseTrackerImpl pendingResponseTracker; - app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, - &mpTestContext->GetExchangeManager(), &pendingResponseTracker); + app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(), + &pendingResponseTracker); app::CommandSender::ConfigParameters configParameters; configParameters.SetRemoteMaxPathsPerInvoke(2); @@ -1735,8 +1717,8 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_AcceptMultipleCom mockCommandSenderExtendedDelegate.ResetCounter(); PendingResponseTrackerImpl pendingResponseTracker; - app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, - &mpTestContext->GetExchangeManager(), &pendingResponseTracker); + app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(), + &pendingResponseTracker); app::CommandSender::ConfigParameters configParameters; configParameters.SetRemoteMaxPathsPerInvoke(2); @@ -1875,15 +1857,15 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_FillUpInvokeRespo TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_ReleaseWithExchangeClosed) { - app::CommandSender commandSender(&mockCommandSenderDelegate, &mpTestContext->GetExchangeManager()); + app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager()); AddInvokeRequestData(&commandSender); asyncCommandHandle = nullptr; asyncCommand = true; - EXPECT_EQ(commandSender.SendCommandRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Verify that async command handle has been allocated ASSERT_NE(asyncCommandHandle.Get(), nullptr); diff --git a/src/app/tests/TestEventLogging.cpp b/src/app/tests/TestEventLogging.cpp index 931b706024c740..cbc42d9060e435 100644 --- a/src/app/tests/TestEventLogging.cpp +++ b/src/app/tests/TestEventLogging.cpp @@ -53,19 +53,9 @@ static uint8_t gInfoEventBuffer[120]; static uint8_t gCritEventBuffer[120]; static chip::app::CircularEventBuffer gCircularEventBuffer[3]; -class TestEventLogging : public ::testing::Test +class TestEventLogging : public chip::Test::AppContext { public: - static void SetUpTestSuite() - { - mpTestContext = new chip::Test::AppContext; - mpTestContext->SetUpTestSuite(); - } - static void TearDownTestSuite() - { - mpTestContext->TearDownTestSuite(); - delete mpTestContext; - } // Performs setup for each individual test in the test suite void SetUp() override { @@ -75,9 +65,9 @@ class TestEventLogging : public ::testing::Test { &gCritEventBuffer[0], sizeof(gCritEventBuffer), chip::app::PriorityLevel::Critical }, }; - mpTestContext->SetUp(); + AppContext::SetUp(); ASSERT_EQ(mEventCounter.Init(0), CHIP_NO_ERROR); - chip::app::EventManagement::CreateEventManagement(&mpTestContext->GetExchangeManager(), ArraySize(logStorageResources), + chip::app::EventManagement::CreateEventManagement(&GetExchangeManager(), ArraySize(logStorageResources), gCircularEventBuffer, logStorageResources, &mEventCounter); } @@ -85,17 +75,13 @@ class TestEventLogging : public ::testing::Test void TearDown() override { chip::app::EventManagement::DestroyEventManagement(); - mpTestContext->TearDown(); + AppContext::TearDown(); } - static chip::Test::AppContext * mpTestContext; - private: chip::MonotonicallyIncreasingCounter mEventCounter; }; -chip::Test::AppContext * TestEventLogging::mpTestContext = nullptr; - void ENFORCE_FORMAT(1, 2) SimpleDumpWriter(const char * aFormat, ...) { va_list args; diff --git a/src/app/tests/TestEventLoggingNoUTCTime.cpp b/src/app/tests/TestEventLoggingNoUTCTime.cpp index 907a85982c1155..f3cfc0e8a30ddc 100644 --- a/src/app/tests/TestEventLoggingNoUTCTime.cpp +++ b/src/app/tests/TestEventLoggingNoUTCTime.cpp @@ -73,14 +73,13 @@ class MockClock : public chip::System::Clock::ClockBase chip::System::Clock::ClockBase & mRealClock; }; -class TestEventLoggingNoUTCTime : public ::testing::Test +class TestEventLoggingNoUTCTime : public chip::Test::AppContext { public: // Performs shared setup for all tests in the test suite static void SetUpTestSuite() { - mpTestContext = new chip::Test::AppContext; - mpTestContext->SetUpTestSuite(); + AppContext::SetUpTestSuite(); sClock.Emplace(chip::System::SystemClock()); } @@ -88,8 +87,7 @@ class TestEventLoggingNoUTCTime : public ::testing::Test static void TearDownTestSuite() { sClock.ClearValue(); - mpTestContext->TearDownTestSuite(); - delete mpTestContext; + AppContext::TearDownTestSuite(); } // Performs setup for each individual test in the test suite @@ -101,9 +99,9 @@ class TestEventLoggingNoUTCTime : public ::testing::Test { &gCritEventBuffer[0], sizeof(gCritEventBuffer), chip::app::PriorityLevel::Critical }, }; - mpTestContext->SetUp(); + AppContext::SetUp(); ASSERT_EQ(mEventCounter.Init(0), CHIP_NO_ERROR); - chip::app::EventManagement::CreateEventManagement(&mpTestContext->GetExchangeManager(), ArraySize(logStorageResources), + chip::app::EventManagement::CreateEventManagement(&GetExchangeManager(), ArraySize(logStorageResources), gCircularEventBuffer, logStorageResources, &mEventCounter); } @@ -111,17 +109,14 @@ class TestEventLoggingNoUTCTime : public ::testing::Test void TearDown() override { chip::app::EventManagement::DestroyEventManagement(); - mpTestContext->TearDown(); + AppContext::TearDown(); } - static chip::Test::AppContext * mpTestContext; - private: chip::MonotonicallyIncreasingCounter mEventCounter; static chip::Optional sClock; }; -chip::Test::AppContext * TestEventLoggingNoUTCTime::mpTestContext = nullptr; chip::Optional TestEventLoggingNoUTCTime::sClock; void ENFORCE_FORMAT(1, 2) SimpleDumpWriter(const char * aFormat, ...) diff --git a/src/app/tests/TestEventOverflow.cpp b/src/app/tests/TestEventOverflow.cpp index 45692273c88274..4a3cc2d80c3613 100644 --- a/src/app/tests/TestEventOverflow.cpp +++ b/src/app/tests/TestEventOverflow.cpp @@ -51,20 +51,9 @@ static uint8_t gInfoEventBuffer[2048]; static uint8_t gCritEventBuffer[2048]; static chip::app::CircularEventBuffer gCircularEventBuffer[3]; -class TestEventOverflow : public ::testing::Test +class TestEventOverflow : public chip::Test::AppContext { public: - static void SetUpTestSuite() - { - mpTestContext = new chip::Test::AppContext; - mpTestContext->SetUpTestSuite(); - } - static void TearDownTestSuite() - { - mpTestContext->TearDownTestSuite(); - delete mpTestContext; - } - // Performs setup for each individual test in the test suite void SetUp() override { @@ -74,9 +63,11 @@ class TestEventOverflow : public ::testing::Test { &gCritEventBuffer[0], sizeof(gCritEventBuffer), chip::app::PriorityLevel::Critical }, }; - mpTestContext->SetUp(); + AppContext::SetUp(); + VerifyOrReturn(!HasFailure()); + ASSERT_EQ(mEventCounter.Init(0), CHIP_NO_ERROR); - chip::app::EventManagement::CreateEventManagement(&mpTestContext->GetExchangeManager(), ArraySize(logStorageResources), + chip::app::EventManagement::CreateEventManagement(&GetExchangeManager(), ArraySize(logStorageResources), gCircularEventBuffer, logStorageResources, &mEventCounter); } @@ -84,17 +75,13 @@ class TestEventOverflow : public ::testing::Test void TearDown() override { chip::app::EventManagement::DestroyEventManagement(); - mpTestContext->TearDown(); + AppContext::TearDown(); } - static chip::Test::AppContext * mpTestContext; - private: chip::MonotonicallyIncreasingCounter mEventCounter; }; -chip::Test::AppContext * TestEventOverflow::mpTestContext = nullptr; - class TestEventGenerator : public chip::app::EventLoggingDelegate { public: diff --git a/src/app/tests/TestFabricScopedEventLogging.cpp b/src/app/tests/TestFabricScopedEventLogging.cpp index d113bc692e069f..d825626688f90b 100644 --- a/src/app/tests/TestFabricScopedEventLogging.cpp +++ b/src/app/tests/TestFabricScopedEventLogging.cpp @@ -53,20 +53,9 @@ static uint8_t gInfoEventBuffer[128]; static uint8_t gCritEventBuffer[128]; static chip::app::CircularEventBuffer gCircularEventBuffer[3]; -class TestFabricScopedEventLogging : public ::testing::Test +class TestFabricScopedEventLogging : public chip::Test::AppContext { public: - static void SetUpTestSuite() - { - mpTestContext = new chip::Test::AppContext; - mpTestContext->SetUpTestSuite(); - } - static void TearDownTestSuite() - { - mpTestContext->TearDownTestSuite(); - delete mpTestContext; - } - // Performs setup for each individual test in the test suite void SetUp() override { @@ -76,10 +65,10 @@ class TestFabricScopedEventLogging : public ::testing::Test { &gCritEventBuffer[0], sizeof(gCritEventBuffer), chip::app::PriorityLevel::Critical }, }; - mpTestContext->SetUp(); + AppContext::SetUp(); ASSERT_EQ(mEventCounter.Init(0), CHIP_NO_ERROR); - chip::app::EventManagement::CreateEventManagement(&mpTestContext->GetExchangeManager(), ArraySize(logStorageResources), + chip::app::EventManagement::CreateEventManagement(&GetExchangeManager(), ArraySize(logStorageResources), gCircularEventBuffer, logStorageResources, &mEventCounter); } @@ -87,15 +76,12 @@ class TestFabricScopedEventLogging : public ::testing::Test void TearDown() override { chip::app::EventManagement::DestroyEventManagement(); - mpTestContext->TearDown(); + AppContext::TearDown(); } - static chip::Test::AppContext * mpTestContext; - private: chip::MonotonicallyIncreasingCounter mEventCounter; }; -chip::Test::AppContext * TestFabricScopedEventLogging::mpTestContext = nullptr; void ENFORCE_FORMAT(1, 2) SimpleDumpWriter(const char * aFormat, ...) { diff --git a/src/app/tests/TestInteractionModelEngine.cpp b/src/app/tests/TestInteractionModelEngine.cpp index 7817d3636d3fae..f724f1921ef81d 100644 --- a/src/app/tests/TestInteractionModelEngine.cpp +++ b/src/app/tests/TestInteractionModelEngine.cpp @@ -42,8 +42,6 @@ #endif // CHIP_CONFIG_PERSIST_SUBSCRIPTIONS namespace { -using TestContext = chip::Test::AppContext; - class NullReadHandlerCallback : public chip::app::ReadHandler::ManagementCallback { public: @@ -59,39 +57,9 @@ class NullReadHandlerCallback : public chip::app::ReadHandler::ManagementCallbac namespace chip { namespace app { -class TestInteractionModelEngine : public ::testing::Test +class TestInteractionModelEngine : public chip::Test::AppContext { public: - static void SetUpTestSuite() - { - mpTestContext = new chip::Test::AppContext; - mpTestContext->SetUpTestSuite(); - } - static void TearDownTestSuite() - { - mpTestContext->TearDownTestSuite(); - if (mpTestContext != nullptr) - { - delete mpTestContext; - } - } - - void SetUp() override - { - - if (mpTestContext != nullptr) - { - mpTestContext->SetUp(); - } - } - void TearDown() override - { - if (mpTestContext != nullptr) - { - mpTestContext->TearDown(); - } - } - void TestSubjectHasActiveSubscriptionSingleSubOneEntry(); void TestSubjectHasActiveSubscriptionSingleSubMultipleEntries(); void TestSubjectHasActiveSubscriptionMultipleSubsSingleEntry(); @@ -100,12 +68,8 @@ class TestInteractionModelEngine : public ::testing::Test void TestSubscriptionResumptionTimer(); void TestDecrementNumSubscriptionsToResume(); static int GetAttributePathListLength(SingleLinkedListNode * apattributePathParamsList); - - static chip::Test::AppContext * mpTestContext; }; -chip::Test::AppContext * TestInteractionModelEngine::mpTestContext = nullptr; - int TestInteractionModelEngine::GetAttributePathListLength(SingleLinkedListNode * apAttributePathParamsList) { int length = 0; @@ -123,9 +87,7 @@ TEST_F(TestInteractionModelEngine, TestAttributePathParamsPushRelease) InteractionModelEngine * engine = InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler()), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); SingleLinkedListNode * attributePathParamsList = nullptr; AttributePathParams attributePathParams1; @@ -160,9 +122,7 @@ TEST_F(TestInteractionModelEngine, TestRemoveDuplicateConcreteAttribute) InteractionModelEngine * engine = InteractionModelEngine::GetInstance(); - EXPECT_EQ(CHIP_NO_ERROR, - engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler())); + EXPECT_EQ(CHIP_NO_ERROR, engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler())); SingleLinkedListNode * attributePathParamsList = nullptr; AttributePathParams attributePathParams1; @@ -294,13 +254,11 @@ TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscription FabricIndex bobFabricIndex = 1; // Create ExchangeContext - Messaging::ExchangeContext * exchangeCtx1 = mpTestContext->NewExchangeToBob(nullptr, false); + Messaging::ExchangeContext * exchangeCtx1 = NewExchangeToBob(nullptr, false); ASSERT_TRUE(exchangeCtx1); // InteractionModelEngine init - EXPECT_EQ(CHIP_NO_ERROR, - engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - reporting::GetDefaultReportScheduler())); + EXPECT_EQ(CHIP_NO_ERROR, engine->Init(&GetExchangeManager(), &GetFabricTable(), reporting::GetDefaultReportScheduler())); // Verify that there are no active subscriptions EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId)); @@ -339,16 +297,14 @@ TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscription FabricIndex bobFabricIndex = 1; // Create ExchangeContexts - Messaging::ExchangeContext * exchangeCtx1 = mpTestContext->NewExchangeToBob(nullptr, false); + Messaging::ExchangeContext * exchangeCtx1 = NewExchangeToBob(nullptr, false); ASSERT_TRUE(exchangeCtx1); - Messaging::ExchangeContext * exchangeCtx2 = mpTestContext->NewExchangeToBob(nullptr, false); + Messaging::ExchangeContext * exchangeCtx2 = NewExchangeToBob(nullptr, false); ASSERT_TRUE(exchangeCtx1); // InteractionModelEngine init - EXPECT_EQ(CHIP_NO_ERROR, - engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - reporting::GetDefaultReportScheduler())); + EXPECT_EQ(CHIP_NO_ERROR, engine->Init(&GetExchangeManager(), &GetFabricTable(), reporting::GetDefaultReportScheduler())); // Verify that both Alice and Bob have no active subscriptions EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId)); @@ -398,16 +354,14 @@ TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscription FabricIndex aliceFabricIndex = 2; // Create ExchangeContexts - Messaging::ExchangeContext * exchangeCtx1 = mpTestContext->NewExchangeToBob(nullptr, false); + Messaging::ExchangeContext * exchangeCtx1 = NewExchangeToBob(nullptr, false); ASSERT_TRUE(exchangeCtx1); - Messaging::ExchangeContext * exchangeCtx2 = mpTestContext->NewExchangeToAlice(nullptr, false); + Messaging::ExchangeContext * exchangeCtx2 = NewExchangeToAlice(nullptr, false); ASSERT_TRUE(exchangeCtx2); // InteractionModelEngine init - EXPECT_EQ(CHIP_NO_ERROR, - engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - reporting::GetDefaultReportScheduler())); + EXPECT_EQ(CHIP_NO_ERROR, engine->Init(&GetExchangeManager(), &GetFabricTable(), reporting::GetDefaultReportScheduler())); // Verify that both Alice and Bob have no active subscriptions EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId)); @@ -474,22 +428,20 @@ TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscription FabricIndex aliceFabricIndex = 2; // Create ExchangeContexts - Messaging::ExchangeContext * exchangeCtx11 = mpTestContext->NewExchangeToBob(nullptr, false); + Messaging::ExchangeContext * exchangeCtx11 = NewExchangeToBob(nullptr, false); ASSERT_TRUE(exchangeCtx11); - Messaging::ExchangeContext * exchangeCtx12 = mpTestContext->NewExchangeToBob(nullptr, false); + Messaging::ExchangeContext * exchangeCtx12 = NewExchangeToBob(nullptr, false); ASSERT_TRUE(exchangeCtx12); - Messaging::ExchangeContext * exchangeCtx21 = mpTestContext->NewExchangeToAlice(nullptr, false); + Messaging::ExchangeContext * exchangeCtx21 = NewExchangeToAlice(nullptr, false); ASSERT_TRUE(exchangeCtx21); - Messaging::ExchangeContext * exchangeCtx22 = mpTestContext->NewExchangeToAlice(nullptr, false); + Messaging::ExchangeContext * exchangeCtx22 = NewExchangeToAlice(nullptr, false); ASSERT_TRUE(exchangeCtx22); // InteractionModelEngine init - EXPECT_EQ(CHIP_NO_ERROR, - engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - reporting::GetDefaultReportScheduler())); + EXPECT_EQ(CHIP_NO_ERROR, engine->Init(&GetExchangeManager(), &GetFabricTable(), reporting::GetDefaultReportScheduler())); // Verify that both Alice and Bob have no active subscriptions EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId)); @@ -566,18 +518,16 @@ TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscription FabricIndex bobFabricIndex = 1; // InteractionModelEngine init - EXPECT_EQ(CHIP_NO_ERROR, - engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - reporting::GetDefaultReportScheduler())); + EXPECT_EQ(CHIP_NO_ERROR, engine->Init(&GetExchangeManager(), &GetFabricTable(), reporting::GetDefaultReportScheduler())); // Make sure we are using CASE sessions, because there is no defunct-marking for PASE. - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->ExpireSessionAliceToBob(); - EXPECT_EQ(CHIP_NO_ERROR, mpTestContext->CreateCASESessionBobToAlice(cats)); - EXPECT_EQ(CHIP_NO_ERROR, mpTestContext->CreateCASESessionAliceToBob(cats)); + ExpireSessionBobToAlice(); + ExpireSessionAliceToBob(); + EXPECT_EQ(CHIP_NO_ERROR, CreateCASESessionBobToAlice(cats)); + EXPECT_EQ(CHIP_NO_ERROR, CreateCASESessionAliceToBob(cats)); // Create ExchangeContexts - Messaging::ExchangeContext * exchangeCtx = mpTestContext->NewExchangeToBob(nullptr, false); + Messaging::ExchangeContext * exchangeCtx = NewExchangeToBob(nullptr, false); ASSERT_TRUE(exchangeCtx); // Create readHandler @@ -618,8 +568,8 @@ TEST_F(TestInteractionModelEngine, TestSubjectHasPersistedSubscription) EXPECT_EQ(subscriptionStorage.Init(&storage), CHIP_NO_ERROR); EXPECT_EQ(CHIP_NO_ERROR, - engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler(), nullptr, &subscriptionStorage)); + engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler(), nullptr, + &subscriptionStorage)); NodeId nodeId1 = 1; FabricIndex fabric1 = 1; @@ -672,9 +622,7 @@ TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubscriptionResumptionTimer) InteractionModelEngine * engine = InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler()), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); uint32_t timeTillNextResubscriptionMs; engine->mNumSubscriptionResumptionRetries = 0; @@ -705,9 +653,7 @@ TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestDecrementNumSubscriptionsToR constexpr uint8_t kNumberOfSubsToResume = 5; uint8_t numberOfSubsRemaining = kNumberOfSubsToResume; - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler()), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); #if CHIP_CONFIG_ENABLE_ICD_CIP && !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION ICDManager manager; diff --git a/src/app/tests/TestReadInteraction.cpp b/src/app/tests/TestReadInteraction.cpp index 561a0997afa2a8..81c66e45f40999 100644 --- a/src/app/tests/TestReadInteraction.cpp +++ b/src/app/tests/TestReadInteraction.cpp @@ -230,14 +230,13 @@ using Seconds16 = System::Clock::Seconds16; using Milliseconds32 = System::Clock::Milliseconds32; // TODO: Add support for a 2nd Test Context by making sSyncScheduler = true (this was not ported from NL Tests yet) -class TestReadInteraction : public ::testing::Test +class TestReadInteraction : public chip::Test::AppContext { public: static void SetUpTestSuite() { - mpTestContext = new chip::Test::AppContext; - mpTestContext->SetUpTestSuite(); + AppContext::SetUpTestSuite(); gRealClock = &chip::System::SystemClock(); chip::System::Clock::Internal::SetSystemClockForTesting(&gMockClock); @@ -256,8 +255,7 @@ class TestReadInteraction : public ::testing::Test { chip::System::Clock::Internal::SetSystemClockForTesting(gRealClock); - mpTestContext->TearDownTestSuite(); - delete mpTestContext; + AppContext::TearDownTestSuite(); } void SetUp() @@ -268,20 +266,18 @@ class TestReadInteraction : public ::testing::Test { &gCritEventBuffer[0], sizeof(gCritEventBuffer), chip::app::PriorityLevel::Critical }, }; - mpTestContext->SetUp(); + AppContext::SetUp(); ASSERT_EQ(mEventCounter.Init(0), CHIP_NO_ERROR); - chip::app::EventManagement::CreateEventManagement(&mpTestContext->GetExchangeManager(), ArraySize(logStorageResources), + chip::app::EventManagement::CreateEventManagement(&GetExchangeManager(), ArraySize(logStorageResources), gCircularEventBuffer, logStorageResources, &mEventCounter); } void TearDown() { chip::app::EventManagement::DestroyEventManagement(); - mpTestContext->TearDown(); + AppContext::TearDown(); } - static chip::Test::AppContext * mpTestContext; - void TestReadClient(); void TestReadUnexpectedSubscriptionId(); void TestReadHandler(); @@ -334,8 +330,7 @@ class TestReadInteraction : public ::testing::Test static bool sSyncScheduler; }; -chip::Test::AppContext * TestReadInteraction::mpTestContext = nullptr; -bool TestReadInteraction::sSyncScheduler = false; +bool TestReadInteraction::sSyncScheduler = false; void TestReadInteraction::GenerateReportData(System::PacketBufferHandle & aPayload, ReportType aReportType, bool aSuppressResponse, bool aHasSubscriptionId = false) @@ -420,19 +415,19 @@ void TestReadInteraction::GenerateReportData(System::PacketBufferHandle & aPaylo TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClient) { MockInteractionModelApp delegate; - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); // We don't actually want to deliver that message, because we want to // synthesize the read response. But we don't want it hanging around // forever either. - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->DrainAndServiceIO(); + GetLoopback().mNumMessagesToDrop = 1; + DrainAndServiceIO(); GenerateReportData(buf, ReportType::kValid, true /* aSuppressResponse*/); EXPECT_EQ(readClient.ProcessReportData(std::move(buf), ReadClient::ReportType::kContinuingTransaction), CHIP_NO_ERROR); @@ -441,19 +436,19 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClient) TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadUnexpectedSubscriptionId) { MockInteractionModelApp delegate; - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); // We don't actually want to deliver that message, because we want to // synthesize the read response. But we don't want it hanging around // forever either. - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->DrainAndServiceIO(); + GetLoopback().mNumMessagesToDrop = 1; + DrainAndServiceIO(); // For read, we don't expect there is subscription id in report data. GenerateReportData(buf, ReportType::kValid, true /* aSuppressResponse*/, true /*aHasSubscriptionId*/); @@ -470,11 +465,10 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandler) NullReadHandlerCallback nullCallback; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); { - Messaging::ExchangeContext * exchangeCtx = mpTestContext->NewExchangeToAlice(nullptr, false); + Messaging::ExchangeContext * exchangeCtx = NewExchangeToAlice(nullptr, false); ReadHandler readHandler(nullCallback, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler); GenerateReportData(reportDatabuf, ReportType::kValid, false /* aSuppressResponse*/); @@ -507,7 +501,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandler) engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientGenerateAttributePathList) @@ -521,7 +515,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientGenerateAttributePathList writer.Init(std::move(msgBuf)); EXPECT_EQ(request.Init(&writer), CHIP_NO_ERROR); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); AttributePathParams attributePathParams[2]; @@ -545,7 +539,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientGenerateInvalidAttributeP EXPECT_FALSE(msgBuf.IsNull()); writer.Init(std::move(msgBuf)); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(request.Init(&writer), CHIP_NO_ERROR); @@ -567,17 +561,17 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientInvalidReport) System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); // We don't actually want to deliver that message, because we want to // synthesize the read response. But we don't want it hanging around // forever either. - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->DrainAndServiceIO(); + GetLoopback().mNumMessagesToDrop = 1; + DrainAndServiceIO(); GenerateReportData(buf, ReportType::kInvalidNoAttributeId, true /* aSuppressResponse*/); @@ -591,17 +585,17 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientInvalidAttributeId) System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); // We don't actually want to deliver that message, because we want to // synthesize the read response. But we don't want it hanging around // forever either. - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->DrainAndServiceIO(); + GetLoopback().mNumMessagesToDrop = 1; + DrainAndServiceIO(); GenerateReportData(buf, ReportType::kInvalidOutOfRangeAttributeId, true /* aSuppressResponse*/); @@ -626,11 +620,10 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandlerInvalidAttributePath) NullReadHandlerCallback nullCallback; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); { - Messaging::ExchangeContext * exchangeCtx = mpTestContext->NewExchangeToAlice(nullptr, false); + Messaging::ExchangeContext * exchangeCtx = NewExchangeToAlice(nullptr, false); ReadHandler readHandler(nullCallback, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler); GenerateReportData(reportDatabuf, ReportType::kValid, false /* aSuppressResponse*/); @@ -669,7 +662,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandlerInvalidAttributePath) } engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientGenerateOneEventPaths) @@ -683,7 +676,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientGenerateOneEventPaths) writer.Init(std::move(msgBuf)); EXPECT_EQ(request.Init(&writer), CHIP_NO_ERROR); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); chip::app::EventPathParams eventPathParams[1]; @@ -710,7 +703,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientGenerateOneEventPaths) readRequestParser.PrettyPrint(); #endif - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientGenerateTwoEventPaths) @@ -724,7 +717,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientGenerateTwoEventPaths) writer.Init(std::move(msgBuf)); EXPECT_EQ(request.Init(&writer), CHIP_NO_ERROR); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); chip::app::EventPathParams eventPathParams[2]; @@ -755,13 +748,13 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientGenerateTwoEventPaths) readRequestParser.PrettyPrint(); #endif - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestReadInteraction, TestReadRoundtrip) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -769,8 +762,7 @@ TEST_F(TestReadInteraction, TestReadRoundtrip) MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); chip::app::EventPathParams eventPathParams[1]; @@ -787,7 +779,7 @@ TEST_F(TestReadInteraction, TestReadRoundtrip) attributePathParams[1].mAttributeId = 2; attributePathParams[1].mListIndex = 1; - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpEventPathParamsList = eventPathParams; readPrepareParams.mEventPathParamsListSize = 1; readPrepareParams.mpAttributePathParamsList = attributePathParams; @@ -795,12 +787,12 @@ TEST_F(TestReadInteraction, TestReadRoundtrip) readPrepareParams.mEventNumber.SetValue(1); { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumDataElementIndex, 1); EXPECT_TRUE(delegate.mGotEventResponse); @@ -814,12 +806,12 @@ TEST_F(TestReadInteraction, TestReadRoundtrip) } { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotEventResponse); EXPECT_EQ(delegate.mNumAttributeResponse, 2); @@ -833,13 +825,13 @@ TEST_F(TestReadInteraction, TestReadRoundtrip) EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestReadInteraction, TestReadRoundtripWithDataVersionFilter) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -847,8 +839,7 @@ TEST_F(TestReadInteraction, TestReadRoundtripWithDataVersionFilter) MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); chip::app::AttributePathParams attributePathParams[2]; @@ -866,19 +857,19 @@ TEST_F(TestReadInteraction, TestReadRoundtripWithDataVersionFilter) dataVersionFilters[0].mClusterId = kTestClusterId; dataVersionFilters[0].mDataVersion.SetValue(kTestDataVersion1); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mAttributePathParamsListSize = 2; readPrepareParams.mpDataVersionFilterList = dataVersionFilters; readPrepareParams.mDataVersionFilterListSize = 1; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 0); delegate.mNumAttributeResponse = 0; @@ -886,13 +877,13 @@ TEST_F(TestReadInteraction, TestReadRoundtripWithDataVersionFilter) EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestReadInteraction, TestReadRoundtripWithNoMatchPathDataVersionFilter) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -900,8 +891,7 @@ TEST_F(TestReadInteraction, TestReadRoundtripWithNoMatchPathDataVersionFilter) MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); chip::app::AttributePathParams attributePathParams[2]; attributePathParams[0].mEndpointId = kTestEndpointId; @@ -922,19 +912,19 @@ TEST_F(TestReadInteraction, TestReadRoundtripWithNoMatchPathDataVersionFilter) dataVersionFilters[1].mClusterId = kTestClusterId; dataVersionFilters[1].mDataVersion.SetValue(kTestDataVersion2); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mAttributePathParamsListSize = 2; readPrepareParams.mpDataVersionFilterList = dataVersionFilters; readPrepareParams.mDataVersionFilterListSize = 2; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 2); EXPECT_FALSE(delegate.mReadError); @@ -943,13 +933,13 @@ TEST_F(TestReadInteraction, TestReadRoundtripWithNoMatchPathDataVersionFilter) EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestReadInteraction, TestReadRoundtripWithMultiSamePathDifferentDataVersionFilter) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -957,8 +947,7 @@ TEST_F(TestReadInteraction, TestReadRoundtripWithMultiSamePathDifferentDataVersi MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); chip::app::AttributePathParams attributePathParams[2]; @@ -980,19 +969,19 @@ TEST_F(TestReadInteraction, TestReadRoundtripWithMultiSamePathDifferentDataVersi dataVersionFilters[1].mClusterId = kTestClusterId; dataVersionFilters[1].mDataVersion.SetValue(kTestDataVersion2); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mAttributePathParamsListSize = 2; readPrepareParams.mpDataVersionFilterList = dataVersionFilters; readPrepareParams.mDataVersionFilterListSize = 2; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 2); EXPECT_FALSE(delegate.mReadError); @@ -1001,13 +990,13 @@ TEST_F(TestReadInteraction, TestReadRoundtripWithMultiSamePathDifferentDataVersi EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestReadInteraction, TestReadRoundtripWithSameDifferentPathsDataVersionFilter) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -1015,8 +1004,7 @@ TEST_F(TestReadInteraction, TestReadRoundtripWithSameDifferentPathsDataVersionFi MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); chip::app::AttributePathParams attributePathParams[2]; @@ -1038,19 +1026,19 @@ TEST_F(TestReadInteraction, TestReadRoundtripWithSameDifferentPathsDataVersionFi dataVersionFilters[1].mClusterId = kTestClusterId; dataVersionFilters[1].mDataVersion.SetValue(kTestDataVersion2); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mAttributePathParamsListSize = 2; readPrepareParams.mpDataVersionFilterList = dataVersionFilters; readPrepareParams.mDataVersionFilterListSize = 2; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 0); EXPECT_FALSE(delegate.mReadError); @@ -1059,13 +1047,13 @@ TEST_F(TestReadInteraction, TestReadRoundtripWithSameDifferentPathsDataVersionFi EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestReadInteraction, TestReadWildcard) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -1073,15 +1061,14 @@ TEST_F(TestReadInteraction, TestReadWildcard) MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); chip::app::AttributePathParams attributePathParams[1]; attributePathParams[0].mEndpointId = chip::Test::kMockEndpoint2; attributePathParams[0].mClusterId = chip::Test::MockClusterId(3); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpEventPathParamsList = nullptr; readPrepareParams.mEventPathParamsListSize = 0; readPrepareParams.mpAttributePathParamsList = attributePathParams; @@ -1089,12 +1076,12 @@ TEST_F(TestReadInteraction, TestReadWildcard) { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 5); EXPECT_TRUE(delegate.mGotReport); EXPECT_FALSE(delegate.mReadError); @@ -1105,14 +1092,14 @@ TEST_F(TestReadInteraction, TestReadWildcard) EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // TestReadChunking will try to read a few large attributes, the report won't fit into the MTU and result in chunking. TEST_F(TestReadInteraction, TestReadChunking) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -1120,8 +1107,7 @@ TEST_F(TestReadInteraction, TestReadChunking) MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); chip::app::AttributePathParams attributePathParams[1]; @@ -1131,19 +1117,19 @@ TEST_F(TestReadInteraction, TestReadChunking) attributePathParams[0].mClusterId = chip::Test::MockClusterId(2); attributePathParams[0].mAttributeId = chip::Test::MockAttributeId(4); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpEventPathParamsList = nullptr; readPrepareParams.mEventPathParamsListSize = 0; readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mAttributePathParamsListSize = 1; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // We get one chunk with 4 array elements, and then one chunk per // element, and the total size of the array is @@ -1159,21 +1145,20 @@ TEST_F(TestReadInteraction, TestReadChunking) EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestReadInteraction, TestSetDirtyBetweenChunks) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); GenerateEvents(); auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); chip::app::AttributePathParams attributePathParams[2]; for (auto & attributePathParam : attributePathParams) @@ -1183,7 +1168,7 @@ TEST_F(TestReadInteraction, TestSetDirtyBetweenChunks) attributePathParam.mAttributeId = chip::Test::MockAttributeId(4); } - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpEventPathParamsList = nullptr; readPrepareParams.mEventPathParamsListSize = 0; readPrepareParams.mpAttributePathParamsList = attributePathParams; @@ -1283,12 +1268,12 @@ TEST_F(TestReadInteraction, TestSetDirtyBetweenChunks) DirtyingMockDelegate delegate(attributePathParams, currentAttributeResponsesWhenSetDirty, currentArrayItemsWhenSetDirty); EXPECT_FALSE(delegate.mGotEventResponse); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Our list has length kMockAttribute4ListLength. Since the underlying // path iterator should be reset to the beginning of the cluster it is @@ -1309,13 +1294,13 @@ TEST_F(TestReadInteraction, TestSetDirtyBetweenChunks) EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestReadInteraction, TestReadInvalidAttributePathRoundtrip) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -1323,8 +1308,7 @@ TEST_F(TestReadInteraction, TestReadInvalidAttributePathRoundtrip) MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); chip::app::AttributePathParams attributePathParams[2]; @@ -1332,17 +1316,17 @@ TEST_F(TestReadInteraction, TestReadInvalidAttributePathRoundtrip) attributePathParams[0].mClusterId = kInvalidTestClusterId; attributePathParams[0].mAttributeId = 1; - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mAttributePathParamsListSize = 1; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 0); // By now we should have closed all exchanges and sent all pending acks, so @@ -1351,7 +1335,7 @@ TEST_F(TestReadInteraction, TestReadInvalidAttributePathRoundtrip) } engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F_FROM_FIXTURE(TestReadInteraction, TestProcessSubscribeRequest) @@ -1360,10 +1344,9 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestProcessSubscribeRequest) System::PacketBufferHandle subscribeRequestbuf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); SubscribeRequestMessage::Builder subscribeRequestBuilder; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); - Messaging::ExchangeContext * exchangeCtx = mpTestContext->NewExchangeToAlice(nullptr, false); + Messaging::ExchangeContext * exchangeCtx = NewExchangeToAlice(nullptr, false); { ReadHandler readHandler(*engine, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler); @@ -1403,7 +1386,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestProcessSubscribeRequest) engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } #if CHIP_CONFIG_ENABLE_ICD_SERVER @@ -1417,13 +1400,12 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestSupMaxInt System::PacketBufferHandle subscribeRequestbuf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); SubscribeRequestMessage::Builder subscribeRequestBuilder; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); uint16_t kMinInterval = 0; uint16_t kMaxIntervalCeiling = 1; - Messaging::ExchangeContext * exchangeCtx = mpTestContext->NewExchangeToAlice(nullptr, false); + Messaging::ExchangeContext * exchangeCtx = NewExchangeToAlice(nullptr, false); { ReadHandler readHandler(*engine, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler); @@ -1471,7 +1453,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestSupMaxInt } engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } /** @@ -1484,13 +1466,12 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestInfMaxInt System::PacketBufferHandle subscribeRequestbuf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); SubscribeRequestMessage::Builder subscribeRequestBuilder; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); uint16_t kMinInterval = 0; uint16_t kMaxIntervalCeiling = 1; - Messaging::ExchangeContext * exchangeCtx = mpTestContext->NewExchangeToAlice(nullptr, false); + Messaging::ExchangeContext * exchangeCtx = NewExchangeToAlice(nullptr, false); { ReadHandler readHandler(*engine, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler); @@ -1538,7 +1519,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestInfMaxInt } engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } /** @@ -1551,13 +1532,12 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestSupMinInt System::PacketBufferHandle subscribeRequestbuf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); SubscribeRequestMessage::Builder subscribeRequestBuilder; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); uint16_t kMinInterval = 305; // Default IdleModeDuration is 300 uint16_t kMaxIntervalCeiling = 605; - Messaging::ExchangeContext * exchangeCtx = mpTestContext->NewExchangeToAlice(nullptr, false); + Messaging::ExchangeContext * exchangeCtx = NewExchangeToAlice(nullptr, false); { ReadHandler readHandler(*engine, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler); @@ -1605,7 +1585,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestSupMinInt } engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } /** @@ -1618,13 +1598,12 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestMaxMinInt System::PacketBufferHandle subscribeRequestbuf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); SubscribeRequestMessage::Builder subscribeRequestBuilder; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); uint16_t kMinInterval = System::Clock::Seconds16::max().count(); uint16_t kMaxIntervalCeiling = System::Clock::Seconds16::max().count(); - Messaging::ExchangeContext * exchangeCtx = mpTestContext->NewExchangeToAlice(nullptr, false); + Messaging::ExchangeContext * exchangeCtx = NewExchangeToAlice(nullptr, false); { ReadHandler readHandler(*engine, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler); @@ -1670,7 +1649,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestMaxMinInt } engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } /** @@ -1683,13 +1662,12 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestInvalidId System::PacketBufferHandle subscribeRequestbuf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); SubscribeRequestMessage::Builder subscribeRequestBuilder; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); uint16_t kMinInterval = 400; uint16_t kMaxIntervalCeiling = 400; - Messaging::ExchangeContext * exchangeCtx = mpTestContext->NewExchangeToAlice(nullptr, false); + Messaging::ExchangeContext * exchangeCtx = NewExchangeToAlice(nullptr, false); { ReadHandler readHandler(*engine, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler); @@ -1735,7 +1713,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestInvalidId } engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } #endif // CHIP_CONFIG_ENABLE_ICD_SERVER @@ -1743,18 +1721,17 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestInvalidId TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeRoundtrip) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::EventPathParams eventPathParams[2]; readPrepareParams.mpEventPathParamsList = eventPathParams; readPrepareParams.mpEventPathParamsList[0].mEndpointId = kTestEventEndpointId; @@ -1784,12 +1761,12 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeRoundtrip) printf("\nSend first subscribe request message to Node: 0x" ChipLogFormatX64 "\n", ChipLogValueX64(chip::kTestDeviceNodeId)); { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); } @@ -1798,12 +1775,12 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeRoundtrip) readPrepareParams.mKeepSubscriptions = false; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); delegate.mGotReport = false; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); ASSERT_NE(engine->ActiveHandlerAt(0), nullptr); @@ -1844,7 +1821,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeRoundtrip) // Advance monotonic timestamp for min interval to elapse gMockClock.AdvanceMonotonic(System::Clock::Seconds16(readPrepareParams.mMinIntervalFloorSeconds)); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); delegate.mGotReport = false; delegate.mGotEventResponse = false; @@ -1854,7 +1831,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeRoundtrip) EXPECT_EQ(engine->GetReportingEngine().SetDirty(dirtyPath2), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); EXPECT_TRUE(delegate.mGotEventResponse); @@ -1863,7 +1840,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeRoundtrip) // Test report with 2 different path, and 1 same path // Advance monotonic timestamp for min interval to elapse gMockClock.AdvanceMonotonic(System::Clock::Seconds16(readPrepareParams.mMinIntervalFloorSeconds)); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); delegate.mGotReport = false; delegate.mNumAttributeResponse = 0; @@ -1871,7 +1848,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeRoundtrip) EXPECT_EQ(engine->GetReportingEngine().SetDirty(dirtyPath2), CHIP_NO_ERROR); EXPECT_EQ(engine->GetReportingEngine().SetDirty(dirtyPath2), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); EXPECT_EQ(delegate.mNumAttributeResponse, 2); @@ -1879,7 +1856,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeRoundtrip) // Test report with 3 different path, and one path is overlapped with another // Advance monotonic timestamp for min interval to elapse gMockClock.AdvanceMonotonic(System::Clock::Seconds16(readPrepareParams.mMinIntervalFloorSeconds)); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); delegate.mGotReport = false; delegate.mNumAttributeResponse = 0; @@ -1887,7 +1864,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeRoundtrip) EXPECT_EQ(engine->GetReportingEngine().SetDirty(dirtyPath2), CHIP_NO_ERROR); EXPECT_EQ(engine->GetReportingEngine().SetDirty(dirtyPath3), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); EXPECT_EQ(delegate.mNumAttributeResponse, 2); @@ -1895,7 +1872,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeRoundtrip) // Test report with 3 different path, all are not overlapped, one path is not interested for current subscription // Advance monotonic timestamp for min interval to elapse gMockClock.AdvanceMonotonic(System::Clock::Seconds16(readPrepareParams.mMinIntervalFloorSeconds)); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); delegate.mGotReport = false; delegate.mNumAttributeResponse = 0; @@ -1903,7 +1880,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeRoundtrip) EXPECT_EQ(engine->GetReportingEngine().SetDirty(dirtyPath2), CHIP_NO_ERROR); EXPECT_EQ(engine->GetReportingEngine().SetDirty(dirtyPath4), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); EXPECT_EQ(delegate.mNumAttributeResponse, 2); @@ -1915,13 +1892,13 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeRoundtrip) // Test empty report // Advance monotonic timestamp for min interval to elapse gMockClock.AdvanceMonotonic(System::Clock::Seconds16(maxInterval)); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); EXPECT_TRUE(engine->GetReportingEngine().IsRunScheduled()); delegate.mGotReport = false; delegate.mNumAttributeResponse = 0; - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 0); } @@ -1932,23 +1909,22 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeRoundtrip) EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeEarlyReport) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::EventPathParams eventPathParams[1]; readPrepareParams.mpEventPathParamsList = eventPathParams; readPrepareParams.mpEventPathParamsList[0].mEndpointId = kTestEventEndpointId; @@ -1965,13 +1941,13 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeEarlyReport) readPrepareParams.mKeepSubscriptions = true; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); readPrepareParams.mpEventPathParamsList[0].mIsUrgentEvent = true; delegate.mGotEventResponse = false; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); System::Clock::Timestamp startTime = gMockClock.GetMonotonicTimestamp(); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); @@ -2009,7 +1985,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeEarlyReport) gMockClock.AdvanceMonotonic(Seconds16(readPrepareParams.mMinIntervalFloorSeconds)); EXPECT_FALSE(InteractionModelEngine::GetInstance()->GetReportingEngine().IsRunScheduled()); // Service Timer expired event - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); EXPECT_GT(gReportScheduler->GetMinTimestampForHandler(delegate.mpReadHandler), gMockClock.GetMonotonicTimestamp()); @@ -2021,10 +1997,10 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeEarlyReport) EXPECT_TRUE(InteractionModelEngine::GetInstance()->GetReportingEngine().IsRunScheduled()); // Service Engine Run - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); // Service EventManagement event - mpTestContext->GetIOContext().DriveIO(); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); + GetIOContext().DriveIO(); EXPECT_TRUE(delegate.mGotEventResponse); } else @@ -2040,14 +2016,14 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeEarlyReport) gMockClock.AdvanceMonotonic(Milliseconds32(50)); // Service Timer expired event - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); EXPECT_TRUE(InteractionModelEngine::GetInstance()->GetReportingEngine().IsRunScheduled()); // Service Engine Run - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); // Service EventManagement event - mpTestContext->GetIOContext().DriveIO(); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); + GetIOContext().DriveIO(); EXPECT_TRUE(delegate.mGotEventResponse); } @@ -2074,7 +2050,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeEarlyReport) EXPECT_FALSE(InteractionModelEngine::GetInstance()->GetReportingEngine().IsRunScheduled()); // Service Timer expired event - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); // Verify the ReadHandler is considered as reportable even if its node's min timestamp has not expired EXPECT_GT(gReportScheduler->GetMaxTimestampForHandler(delegate.mpReadHandler), gMockClock.GetMonotonicTimestamp()); @@ -2083,35 +2059,34 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeEarlyReport) EXPECT_FALSE(delegate.mpReadHandler->IsDirty()); EXPECT_TRUE(InteractionModelEngine::GetInstance()->GetReportingEngine().IsRunScheduled()); // Service Engine Run - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); // Service EventManagement event - mpTestContext->GetIOContext().DriveIO(); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); + GetIOContext().DriveIO(); EXPECT_TRUE(gReportScheduler->IsReportScheduled(delegate.mpReadHandler)); EXPECT_FALSE(InteractionModelEngine::GetInstance()->GetReportingEngine().IsRunScheduled()); } - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeUrgentWildcardEvent) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; MockInteractionModelApp nonUrgentDelegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); EXPECT_FALSE(nonUrgentDelegate.mGotEventResponse); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::EventPathParams eventPathParams[2]; readPrepareParams.mpEventPathParamsList = eventPathParams; readPrepareParams.mpEventPathParamsList[0].mEndpointId = kTestEventEndpointId; @@ -2134,18 +2109,18 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeUrgentWildcardEvent) readPrepareParams.mKeepSubscriptions = true; { - app::ReadClient nonUrgentReadClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), + app::ReadClient nonUrgentReadClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), nonUrgentDelegate, chip::app::ReadClient::InteractionType::Subscribe); nonUrgentDelegate.mGotReport = false; EXPECT_EQ(nonUrgentReadClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); readPrepareParams.mpEventPathParamsList[0].mIsUrgentEvent = true; delegate.mGotReport = false; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); System::Clock::Timestamp startTime = gMockClock.GetMonotonicTimestamp(); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 2u); @@ -2178,7 +2153,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeUrgentWildcardEvent) // Advance monotonic looping to allow events to trigger gMockClock.AdvanceMonotonic(System::Clock::Milliseconds32(600)); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); EXPECT_FALSE(delegate.mGotEventResponse); EXPECT_FALSE(nonUrgentDelegate.mGotEventResponse); @@ -2187,13 +2162,13 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeUrgentWildcardEvent) gMockClock.AdvanceMonotonic(System::Clock::Milliseconds32(800)); // Service Timer expired event - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); // Service Engine Run - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); // Service EventManagement event - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); EXPECT_TRUE(delegate.mGotEventResponse); @@ -2217,7 +2192,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeUrgentWildcardEvent) // Advance monotonic timestamp for min interval to elapse gMockClock.AdvanceMonotonic(System::Clock::Milliseconds32(2100)); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); // No reporting should have happened. EXPECT_FALSE(delegate.mGotEventResponse); @@ -2260,7 +2235,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeUrgentWildcardEvent) EXPECT_FALSE(delegate.mGotEventResponse); EXPECT_FALSE(nonUrgentDelegate.mGotEventResponse); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Should get those urgent events reported. EXPECT_TRUE(delegate.mGotEventResponse); @@ -2286,7 +2261,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeUrgentWildcardEvent) // Advance monotonic timestamp for min interval to elapse gMockClock.AdvanceMonotonic(System::Clock::Milliseconds32(2100)); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); // No reporting should have happened. EXPECT_FALSE(delegate.mGotEventResponse); @@ -2324,7 +2299,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeUrgentWildcardEvent) EXPECT_FALSE(delegate.mGotEventResponse); EXPECT_FALSE(nonUrgentDelegate.mGotEventResponse); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Should get those urgent events reported and the non urgent reported for synchronisation EXPECT_TRUE(delegate.mGotEventResponse); @@ -2338,13 +2313,13 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeUrgentWildcardEvent) EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestReadInteraction, TestSubscribeWildcard) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -2352,11 +2327,10 @@ TEST_F(TestReadInteraction, TestSubscribeWildcard) MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mEventPathParamsListSize = 0; std::unique_ptr attributePathParams(new chip::app::AttributePathParams[2]); @@ -2369,7 +2343,7 @@ TEST_F(TestReadInteraction, TestSubscribeWildcard) printf("\nSend subscribe request message to Node: 0x" ChipLogFormatX64 "\n", ChipLogValueX64(chip::kTestDeviceNodeId)); { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); delegate.mGotReport = false; @@ -2377,7 +2351,7 @@ TEST_F(TestReadInteraction, TestSubscribeWildcard) attributePathParams.release(); EXPECT_EQ(readClient.SendAutoResubscribeRequest(std::move(readPrepareParams)), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); @@ -2439,7 +2413,7 @@ TEST_F(TestReadInteraction, TestSubscribeWildcard) EXPECT_EQ(engine->GetReportingEngine().SetDirty(dirtyPath), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); // We subscribed wildcard path twice, so we will receive two reports here. @@ -2465,7 +2439,7 @@ TEST_F(TestReadInteraction, TestSubscribeWildcard) do { last = delegate.mNumAttributeResponse; - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); } while (last != delegate.mNumAttributeResponse); // Mock endpoint3 has 13 attributes in total, and we subscribed twice. @@ -2484,24 +2458,23 @@ TEST_F(TestReadInteraction, TestSubscribeWildcard) EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // Subscribe (wildcard, C3, A1), then setDirty (E2, C3, wildcard), receive one attribute after setDirty TEST_F(TestReadInteraction, TestSubscribePartialOverlap) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mEventPathParamsListSize = 0; std::unique_ptr attributePathParams(new chip::app::AttributePathParams[2]); @@ -2515,7 +2488,7 @@ TEST_F(TestReadInteraction, TestSubscribePartialOverlap) printf("\nSend subscribe request message to Node: 0x" ChipLogFormatX64 "\n", ChipLogValueX64(chip::kTestDeviceNodeId)); { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); delegate.mGotReport = false; @@ -2523,7 +2496,7 @@ TEST_F(TestReadInteraction, TestSubscribePartialOverlap) attributePathParams.release(); EXPECT_EQ(readClient.SendAutoResubscribeRequest(std::move(readPrepareParams)), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); @@ -2543,7 +2516,7 @@ TEST_F(TestReadInteraction, TestSubscribePartialOverlap) EXPECT_EQ(engine->GetReportingEngine().SetDirty(dirtyPath), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); EXPECT_EQ(delegate.mNumAttributeResponse, 1); @@ -2555,24 +2528,23 @@ TEST_F(TestReadInteraction, TestSubscribePartialOverlap) EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // Subscribe (E2, C3, A1), then setDirty (wildcard, wildcard, wildcard), receive one attribute after setDirty TEST_F(TestReadInteraction, TestSubscribeSetDirtyFullyOverlap) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mEventPathParamsListSize = 0; std::unique_ptr attributePathParams(new chip::app::AttributePathParams[1]); @@ -2587,7 +2559,7 @@ TEST_F(TestReadInteraction, TestSubscribeSetDirtyFullyOverlap) printf("\nSend subscribe request message to Node: 0x" ChipLogFormatX64 "\n", ChipLogValueX64(chip::kTestDeviceNodeId)); { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); delegate.mGotReport = false; @@ -2595,7 +2567,7 @@ TEST_F(TestReadInteraction, TestSubscribeSetDirtyFullyOverlap) attributePathParams.release(); EXPECT_EQ(readClient.SendAutoResubscribeRequest(std::move(readPrepareParams)), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); @@ -2612,7 +2584,7 @@ TEST_F(TestReadInteraction, TestSubscribeSetDirtyFullyOverlap) AttributePathParams dirtyPath; EXPECT_EQ(engine->GetReportingEngine().SetDirty(dirtyPath), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); EXPECT_EQ(delegate.mNumAttributeResponse, 1); @@ -2624,20 +2596,20 @@ TEST_F(TestReadInteraction, TestSubscribeSetDirtyFullyOverlap) EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // Verify that subscription can be shut down just after receiving SUBSCRIBE RESPONSE, // before receiving any subsequent REPORT DATA. TEST_F(TestReadInteraction, TestSubscribeEarlyShutdown) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); InteractionModelEngine & engine = *InteractionModelEngine::GetInstance(); MockInteractionModelApp delegate; // Initialize Interaction Model Engine EXPECT_EQ(rm->TestGetCountRetransTable(), 0); - EXPECT_EQ(engine.Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); + EXPECT_EQ(engine.Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); // Subscribe to the attribute AttributePathParams attributePathParams; @@ -2645,7 +2617,7 @@ TEST_F(TestReadInteraction, TestSubscribeEarlyShutdown) attributePathParams.mClusterId = kTestClusterId; attributePathParams.mAttributeId = 1; - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpAttributePathParamsList = &attributePathParams; readPrepareParams.mAttributePathParamsListSize = 1; readPrepareParams.mMinIntervalFloorSeconds = 2; @@ -2655,12 +2627,12 @@ TEST_F(TestReadInteraction, TestSubscribeEarlyShutdown) printf("Send subscribe request message to Node: 0x" ChipLogFormatX64 "\n", ChipLogValueX64(chip::kTestDeviceNodeId)); { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); EXPECT_EQ(delegate.mNumAttributeResponse, 1); @@ -2675,13 +2647,13 @@ TEST_F(TestReadInteraction, TestSubscribeEarlyShutdown) EXPECT_EQ(rm->TestGetCountRetransTable(), 0); engine.Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeInvalidAttributePathRoundtrip) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -2690,11 +2662,10 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeInvalidAttributePathRoundt MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::AttributePathParams attributePathParams[1]; readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mpAttributePathParamsList[0].mEndpointId = kTestEndpointId; @@ -2703,20 +2674,20 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeInvalidAttributePathRoundt readPrepareParams.mAttributePathParamsListSize = 1; - readPrepareParams.mSessionHolder.Grab(mpTestContext->GetSessionBobToAlice()); + readPrepareParams.mSessionHolder.Grab(GetSessionBobToAlice()); readPrepareParams.mMinIntervalFloorSeconds = 0; readPrepareParams.mMaxIntervalCeilingSeconds = 1; printf("\nSend subscribe request message to Node: 0x" ChipLogFormatX64 "\n", ChipLogValueX64(chip::kTestDeviceNodeId)); { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); delegate.mNumAttributeResponse = 0; - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 0); @@ -2729,19 +2700,19 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeInvalidAttributePathRoundt // Advance monotonic timestamp for min interval to elapse gMockClock.AdvanceMonotonic(System::Clock::Seconds16(maxInterval)); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); EXPECT_TRUE(engine->GetReportingEngine().IsRunScheduled()); EXPECT_TRUE(engine->GetReportingEngine().IsRunScheduled()); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 0); } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestReadInteraction, TestReadShutdown) @@ -2755,7 +2726,7 @@ TEST_F(TestReadInteraction, TestReadShutdown) // for (auto & client : pClients) { - client = Platform::New(engine, &mpTestContext->GetExchangeManager(), delegate, + client = Platform::New(engine, &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); } @@ -2784,7 +2755,7 @@ TEST_F(TestReadInteraction, TestReadShutdown) TEST_F(TestReadInteraction, TestSubscribeInvalidInterval) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -2792,11 +2763,10 @@ TEST_F(TestReadInteraction, TestSubscribeInvalidInterval) MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::AttributePathParams attributePathParams[1]; readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mpAttributePathParamsList[0].mEndpointId = kTestEndpointId; @@ -2805,41 +2775,40 @@ TEST_F(TestReadInteraction, TestSubscribeInvalidInterval) readPrepareParams.mAttributePathParamsListSize = 1; - readPrepareParams.mSessionHolder.Grab(mpTestContext->GetSessionBobToAlice()); + readPrepareParams.mSessionHolder.Grab(GetSessionBobToAlice()); readPrepareParams.mMinIntervalFloorSeconds = 6; readPrepareParams.mMaxIntervalCeilingSeconds = 5; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_ERROR_INVALID_ARGUMENT); printf("\nSend subscribe request message to Node: 0x" ChipLogFormatX64 "\n", ChipLogValueX64(chip::kTestDeviceNodeId)); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F_FROM_FIXTURE(TestReadInteraction, TestPostSubscribeRoundtripStatusReportTimeout) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::EventPathParams eventPathParams[2]; readPrepareParams.mpEventPathParamsList = eventPathParams; readPrepareParams.mpEventPathParamsList[0].mEndpointId = kTestEventEndpointId; @@ -2871,14 +2840,14 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestPostSubscribeRoundtripStatusReportT readPrepareParams.mKeepSubscriptions = false; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); printf("\nSend first subscribe request message to Node: 0x" ChipLogFormatX64 "\n", ChipLogValueX64(chip::kTestDeviceNodeId)); delegate.mGotReport = false; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); ASSERT_NE(engine->ActiveHandlerAt(0), nullptr); @@ -2907,18 +2876,18 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestPostSubscribeRoundtripStatusReportT EXPECT_EQ(engine->GetReportingEngine().SetDirty(dirtyPath2), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); EXPECT_EQ(delegate.mNumAttributeResponse, 2); // Wait for max interval to elapse gMockClock.AdvanceMonotonic(System::Clock::Seconds16(readPrepareParams.mMaxIntervalCeilingSeconds)); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); delegate.mGotReport = false; delegate.mNumAttributeResponse = 0; - mpTestContext->ExpireSessionBobToAlice(); + ExpireSessionBobToAlice(); EXPECT_EQ(engine->GetReportingEngine().SetDirty(dirtyPath1), CHIP_NO_ERROR); @@ -2926,9 +2895,9 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestPostSubscribeRoundtripStatusReportT EXPECT_TRUE(engine->GetReportingEngine().IsRunScheduled()); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); - mpTestContext->ExpireSessionAliceToBob(); + ExpireSessionAliceToBob(); EXPECT_EQ(engine->GetReportingEngine().GetNumReportsInFlight(), 0u); EXPECT_EQ(delegate.mNumAttributeResponse, 0); } @@ -2939,25 +2908,24 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestPostSubscribeRoundtripStatusReportT EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } TEST_F(TestReadInteraction, TestSubscribeRoundtripStatusReportTimeout) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::EventPathParams eventPathParams[2]; readPrepareParams.mpEventPathParamsList = eventPathParams; readPrepareParams.mpEventPathParamsList[0].mEndpointId = kTestEventEndpointId; @@ -2989,18 +2957,18 @@ TEST_F(TestReadInteraction, TestSubscribeRoundtripStatusReportTimeout) readPrepareParams.mKeepSubscriptions = false; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); printf("\nSend first subscribe request message to Node: 0x" ChipLogFormatX64 "\n", ChipLogValueX64(chip::kTestDeviceNodeId)); delegate.mGotReport = false; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->ExpireSessionAliceToBob(); + ExpireSessionAliceToBob(); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); - mpTestContext->ExpireSessionBobToAlice(); + ExpireSessionBobToAlice(); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 0u); EXPECT_EQ(engine->GetReportingEngine().GetNumReportsInFlight(), 0u); @@ -3013,15 +2981,15 @@ TEST_F(TestReadInteraction, TestSubscribeRoundtripStatusReportTimeout) EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } TEST_F(TestReadInteraction, TestReadChunkingStatusReportTimeout) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -3029,8 +2997,7 @@ TEST_F(TestReadInteraction, TestReadChunkingStatusReportTimeout) MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); chip::app::AttributePathParams attributePathParams[1]; @@ -3039,21 +3006,21 @@ TEST_F(TestReadInteraction, TestReadChunkingStatusReportTimeout) attributePathParams[0].mClusterId = chip::Test::MockClusterId(2); attributePathParams[0].mAttributeId = chip::Test::MockAttributeId(4); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpEventPathParamsList = nullptr; readPrepareParams.mEventPathParamsListSize = 0; readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mAttributePathParamsListSize = 1; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->DrainAndServiceIO(); - mpTestContext->ExpireSessionBobToAlice(); + ExpireSessionAliceToBob(); + DrainAndServiceIO(); + ExpireSessionBobToAlice(); EXPECT_EQ(engine->GetReportingEngine().GetNumReportsInFlight(), 0u); // By now we should have closed all exchanges and sent all pending acks, so @@ -3063,9 +3030,9 @@ TEST_F(TestReadInteraction, TestReadChunkingStatusReportTimeout) EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // ReadClient sends the read request, but handler fails to send the one report (SendMessage returns an error). @@ -3074,14 +3041,13 @@ TEST_F(TestReadInteraction, TestReadChunkingStatusReportTimeout) TEST_F(TestReadInteraction, TestReadReportFailure) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); chip::app::AttributePathParams attributePathParams[1]; @@ -3089,47 +3055,46 @@ TEST_F(TestReadInteraction, TestReadReportFailure) attributePathParams[0].mClusterId = chip::Test::MockClusterId(3); attributePathParams[0].mAttributeId = chip::Test::MockAttributeId(1); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpEventPathParamsList = nullptr; readPrepareParams.mEventPathParamsListSize = 0; readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mAttributePathParamsListSize = 1; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeError = 1; - mpTestContext->GetLoopback().mMessageSendError = CHIP_ERROR_INCORRECT_STATE; + GetLoopback().mNumMessagesToAllowBeforeError = 1; + GetLoopback().mMessageSendError = CHIP_ERROR_INCORRECT_STATE; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(engine->GetReportingEngine().GetNumReportsInFlight(), 0u); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 0u); - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeError = 0; - mpTestContext->GetLoopback().mMessageSendError = CHIP_NO_ERROR; + GetLoopback().mNumMessagesToAllowBeforeError = 0; + GetLoopback().mMessageSendError = CHIP_NO_ERROR; } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestReadInteraction, TestSubscribeRoundtripChunkStatusReportTimeout) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::EventPathParams eventPathParams[2]; readPrepareParams.mpEventPathParamsList = eventPathParams; readPrepareParams.mpEventPathParamsList[0].mEndpointId = kTestEventEndpointId; @@ -3158,16 +3123,16 @@ TEST_F(TestReadInteraction, TestSubscribeRoundtripChunkStatusReportTimeout) readPrepareParams.mKeepSubscriptions = false; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); printf("\nSend first subscribe request message to Node: 0x" ChipLogFormatX64 "\n", ChipLogValueX64(chip::kTestDeviceNodeId)); delegate.mGotReport = false; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->DrainAndServiceIO(); - mpTestContext->ExpireSessionBobToAlice(); + ExpireSessionAliceToBob(); + DrainAndServiceIO(); + ExpireSessionBobToAlice(); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 0u); EXPECT_EQ(engine->GetReportingEngine().GetNumReportsInFlight(), 0u); @@ -3180,25 +3145,24 @@ TEST_F(TestReadInteraction, TestSubscribeRoundtripChunkStatusReportTimeout) EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } TEST_F(TestReadInteraction, TestPostSubscribeRoundtripChunkStatusReportTimeout) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::EventPathParams eventPathParams[2]; readPrepareParams.mpEventPathParamsList = eventPathParams; readPrepareParams.mpEventPathParamsList[0].mEndpointId = kTestEventEndpointId; @@ -3227,14 +3191,14 @@ TEST_F(TestReadInteraction, TestPostSubscribeRoundtripChunkStatusReportTimeout) readPrepareParams.mKeepSubscriptions = false; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); printf("\nSend first subscribe request message to Node: 0x" ChipLogFormatX64 "\n", ChipLogValueX64(chip::kTestDeviceNodeId)); delegate.mGotReport = false; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); ASSERT_NE(engine->ActiveHandlerAt(0), nullptr); @@ -3250,55 +3214,54 @@ TEST_F(TestReadInteraction, TestPostSubscribeRoundtripChunkStatusReportTimeout) dirtyPath1.mAttributeId = chip::Test::MockAttributeId(4); gMockClock.AdvanceMonotonic(System::Clock::Seconds16(readPrepareParams.mMaxIntervalCeilingSeconds)); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); EXPECT_EQ(engine->GetReportingEngine().SetDirty(dirtyPath1), CHIP_NO_ERROR); delegate.mGotReport = false; delegate.mNumAttributeResponse = 0; - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 1; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 1; + GetLoopback().mDroppedMessageCount = 0; - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Drop status report for the first chunked report, then expire session, handler would be timeout EXPECT_EQ(engine->GetReportingEngine().GetNumReportsInFlight(), 1u); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 0u); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } TEST_F(TestReadInteraction, TestPostSubscribeRoundtripChunkReportTimeout) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::EventPathParams eventPathParams[2]; readPrepareParams.mpEventPathParamsList = eventPathParams; readPrepareParams.mpEventPathParamsList[0].mEndpointId = kTestEventEndpointId; @@ -3327,14 +3290,14 @@ TEST_F(TestReadInteraction, TestPostSubscribeRoundtripChunkReportTimeout) readPrepareParams.mKeepSubscriptions = false; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); printf("\nSend first subscribe request message to Node: 0x" ChipLogFormatX64 "\n", ChipLogValueX64(chip::kTestDeviceNodeId)); delegate.mGotReport = false; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); ASSERT_NE(engine->ActiveHandlerAt(0), nullptr); @@ -3350,7 +3313,7 @@ TEST_F(TestReadInteraction, TestPostSubscribeRoundtripChunkReportTimeout) dirtyPath1.mAttributeId = chip::Test::MockAttributeId(4); gMockClock.AdvanceMonotonic(System::Clock::Seconds16(readPrepareParams.mMaxIntervalCeilingSeconds)); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); EXPECT_EQ(engine->GetReportingEngine().SetDirty(dirtyPath1), CHIP_NO_ERROR); @@ -3358,46 +3321,45 @@ TEST_F(TestReadInteraction, TestPostSubscribeRoundtripChunkReportTimeout) delegate.mNumAttributeResponse = 0; // Drop second chunked report then expire session, client would be timeout - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 2; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 2; + GetLoopback().mDroppedMessageCount = 0; - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(engine->GetReportingEngine().GetNumReportsInFlight(), 1u); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 3u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 3u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); EXPECT_EQ(delegate.mError, CHIP_ERROR_TIMEOUT); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } TEST_F(TestReadInteraction, TestPostSubscribeRoundtripChunkReport) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::EventPathParams eventPathParams[2]; readPrepareParams.mpEventPathParamsList = eventPathParams; readPrepareParams.mpEventPathParamsList[0].mEndpointId = kTestEventEndpointId; @@ -3426,14 +3388,14 @@ TEST_F(TestReadInteraction, TestPostSubscribeRoundtripChunkReport) readPrepareParams.mKeepSubscriptions = false; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); printf("\nSend first subscribe request message to Node: 0x" ChipLogFormatX64 "\n", ChipLogValueX64(chip::kTestDeviceNodeId)); delegate.mGotReport = false; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); ASSERT_NE(engine->ActiveHandlerAt(0), nullptr); @@ -3456,7 +3418,7 @@ TEST_F(TestReadInteraction, TestPostSubscribeRoundtripChunkReport) // wait for min interval 1 seconds(in test, we use 0.9second considering the time variation), expect no event is // received, then wait for 0.5 seconds, then all chunked dirty reports are sent out, which would not honor minInterval gMockClock.AdvanceMonotonic(System::Clock::Milliseconds32(900)); - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 0); System::Clock::Timestamp startTime = gMockClock.GetMonotonicTimestamp(); @@ -3465,7 +3427,7 @@ TEST_F(TestReadInteraction, TestPostSubscribeRoundtripChunkReport) // be rescheduled accordingly while (true) { - mpTestContext->GetIOContext().DriveIO(); + GetIOContext().DriveIO(); if ((gMockClock.GetMonotonicTimestamp() - startTime) >= System::Clock::Milliseconds32(500)) { break; @@ -3501,16 +3463,15 @@ void CheckForInvalidAction(Test::MessageCapturer & messageLog) TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientReceiveInvalidMessage) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::AttributePathParams attributePathParams[2]; readPrepareParams.mpAttributePathParamsList = attributePathParams; @@ -3525,20 +3486,19 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientReceiveInvalidMessage) readPrepareParams.mAttributePathParamsListSize = 2; { - app::ReadClient readClient(engine, &mpTestContext->GetExchangeManager(), delegate, - chip::app::ReadClient::InteractionType::Read); + app::ReadClient readClient(engine, &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 1; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 1; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes); EXPECT_FALSE(msgBuf.IsNull()); @@ -3552,21 +3512,21 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientReceiveInvalidMessage) payloadHeader.SetExchangeID(0); payloadHeader.SetMessageType(chip::Protocols::InteractionModel::MsgType::StatusResponse); - chip::Test::MessageCapturer messageLog(*mpTestContext); + chip::Test::MessageCapturer messageLog(*this); messageLog.mCaptureStandaloneAcks = false; // Since we are dropping packets, things are not getting acked. Set up // our MRP state to look like what it would have looked like if the // packet had not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, readClient.mExchange.Get()); + PretendWeGotReplyFromServer(*this, readClient.mExchange.Get()); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; readClient.OnMessageReceived(readClient.mExchange.Get(), payloadHeader, std::move(msgBuf)); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // The ReadHandler closed its exchange when it sent the Report Data (which we dropped). // Since we synthesized the StatusResponse to the ReadClient, instead of sending it from the ReadHandler, @@ -3577,10 +3537,10 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientReceiveInvalidMessage) } engine->Shutdown(); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // Read Client sends the subscribe request, Read Handler drops the response, then test injects unknown status response message @@ -3588,16 +3548,15 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadClientReceiveInvalidMessage) TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveInvalidStatusResponse) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::AttributePathParams attributePathParams[2]; readPrepareParams.mpAttributePathParamsList = attributePathParams; @@ -3615,17 +3574,17 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveInvalidStatus readPrepareParams.mMaxIntervalCeilingSeconds = 5; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 1; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 1; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes); EXPECT_FALSE(msgBuf.IsNull()); @@ -3642,37 +3601,37 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveInvalidStatus // Since we are dropping packets, things are not getting acked. Set up // our MRP state to look like what it would have looked like if the // packet had not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, readClient.mExchange.Get()); + PretendWeGotReplyFromServer(*this, readClient.mExchange.Get()); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); ASSERT_NE(engine->ActiveHandlerAt(0), nullptr); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; readClient.OnMessageReceived(readClient.mExchange.Get(), payloadHeader, std::move(msgBuf)); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // TODO: Need to validate what status is being sent to the ReadHandler // The ReadHandler's exchange is closed when we synthesize the subscribe response, since it sent the // Subscribe Response as the last message in the transaction. // Since we synthesized the subscribe response to the ReadClient, instead of sending it from the ReadHandler, // the only messages here are the ReadClient's StatusResponse to the unexpected message and an MRP ack. - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); EXPECT_EQ(delegate.mError, CHIP_IM_GLOBAL_STATUS(Busy)); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 0u); } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // Read Client sends the subscribe request, Read Handler drops the response, then test injects well-formed status response @@ -3680,16 +3639,15 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveInvalidStatus TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveWellFormedStatusResponse) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::AttributePathParams attributePathParams[2]; readPrepareParams.mpAttributePathParamsList = attributePathParams; @@ -3707,17 +3665,17 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveWellFormedSta readPrepareParams.mMaxIntervalCeilingSeconds = 5; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 1; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 1; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes); EXPECT_FALSE(msgBuf.IsNull()); @@ -3734,36 +3692,36 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveWellFormedSta // Since we are dropping packets, things are not getting acked. Set up // our MRP state to look like what it would have looked like if the // packet had not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, readClient.mExchange.Get()); + PretendWeGotReplyFromServer(*this, readClient.mExchange.Get()); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); ASSERT_NE(engine->ActiveHandlerAt(0), nullptr); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; readClient.OnMessageReceived(readClient.mExchange.Get(), payloadHeader, std::move(msgBuf)); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // TODO: Need to validate what status is being sent to the ReadHandler // The ReadHandler's exchange is still open when we synthesize the StatusResponse. // Since we synthesized the StatusResponse to the ReadClient, instead of sending it from the ReadHandler, // the only messages here are the ReadClient's StatusResponse to the unexpected message and an MRP ack. - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); EXPECT_EQ(delegate.mError, CHIP_ERROR_INVALID_MESSAGE_TYPE); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 0u); } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // Read Client sends the subscribe request, Read Handler drops the response, then test injects invalid report message for Read @@ -3771,16 +3729,15 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveWellFormedSta TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveInvalidReportMessage) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::AttributePathParams attributePathParams[2]; readPrepareParams.mpAttributePathParamsList = attributePathParams; @@ -3798,17 +3755,17 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveInvalidReport readPrepareParams.mMaxIntervalCeilingSeconds = 5; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 1; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 1; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes); EXPECT_FALSE(msgBuf.IsNull()); @@ -3824,26 +3781,26 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveInvalidReport // Since we are dropping packets, things are not getting acked. Set up // our MRP state to look like what it would have looked like if the // packet had not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, readClient.mExchange.Get()); + PretendWeGotReplyFromServer(*this, readClient.mExchange.Get()); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); ASSERT_NE(engine->ActiveHandlerAt(0), nullptr); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; readClient.OnMessageReceived(readClient.mExchange.Get(), payloadHeader, std::move(msgBuf)); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // TODO: Need to validate what status is being sent to the ReadHandler // The ReadHandler's exchange is still open when we synthesize the ReportData. // Since we synthesized the ReportData to the ReadClient, instead of sending it from the ReadHandler, // the only messages here are the ReadClient's StatusResponse to the unexpected message and an MRP ack. - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); EXPECT_EQ(delegate.mError, CHIP_ERROR_END_OF_TLV); @@ -3851,10 +3808,10 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveInvalidReport } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // Read Client create the subscription, handler sends unsolicited malformed report to client, @@ -3862,16 +3819,15 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveInvalidReport TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveUnsolicitedInvalidReportMessage) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::AttributePathParams attributePathParams[2]; readPrepareParams.mpAttributePathParamsList = attributePathParams; @@ -3889,13 +3845,13 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveUnsolicitedIn readPrepareParams.mMaxIntervalCeilingSeconds = 5; { - mpTestContext->GetLoopback().mSentMessageCount = 0; - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + GetLoopback().mSentMessageCount = 0; + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 5u); + DrainAndServiceIO(); + EXPECT_EQ(GetLoopback().mSentMessageCount, 5u); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); ASSERT_NE(engine->ActiveHandlerAt(0), nullptr); delegate.mpReadHandler = engine->ActiveHandlerAt(0); @@ -3908,8 +3864,8 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveUnsolicitedIn response.Init(&writer); EXPECT_EQ(writer.Finalize(&msgBuf), CHIP_NO_ERROR); - mpTestContext->GetLoopback().mSentMessageCount = 0; - auto exchange = InteractionModelEngine::GetInstance()->GetExchangeManager()->NewContext( + GetLoopback().mSentMessageCount = 0; + auto exchange = InteractionModelEngine::GetInstance()->GetExchangeManager()->NewContext( delegate.mpReadHandler->mSessionHandle.Get().Value(), delegate.mpReadHandler); delegate.mpReadHandler->mExchangeCtx.Grab(exchange); @@ -3918,12 +3874,12 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveUnsolicitedIn std::move(msgBuf), Messaging::SendMessageFlags::kExpectResponse), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // The server sends a data report. // The client receives the data report data and sends out status report with invalid action. // The server acks the status report. - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 3u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 3u); } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); @@ -3934,16 +3890,15 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveUnsolicitedIn TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveInvalidSubscribeResponseMessage) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::AttributePathParams attributePathParams[2]; readPrepareParams.mpAttributePathParamsList = attributePathParams; @@ -3961,17 +3916,17 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveInvalidSubscr readPrepareParams.mMaxIntervalCeilingSeconds = 5; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 3; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 3; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes); EXPECT_FALSE(msgBuf.IsNull()); @@ -3990,35 +3945,35 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveInvalidSubscr // Since we are dropping packets, things are not getting acked. Set up // our MRP state to look like what it would have looked like if the // packet had not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, readClient.mExchange.Get()); + PretendWeGotReplyFromServer(*this, readClient.mExchange.Get()); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 4u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 4u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); ASSERT_NE(engine->ActiveHandlerAt(0), nullptr); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; readClient.OnMessageReceived(readClient.mExchange.Get(), payloadHeader, std::move(msgBuf)); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // TODO: Need to validate what status is being sent to the ReadHandler // The ReadHandler's exchange is still open when we synthesize the subscribe response. // Since we synthesized the subscribe response to the ReadClient, instead of sending it from the ReadHandler, // the only messages here are the ReadClient's StatusResponse to the unexpected message and an MRP ack. - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); EXPECT_EQ(delegate.mError, CHIP_ERROR_INVALID_SUBSCRIPTION); } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // Read Client create the subscription, handler sends unsolicited malformed report with invalid subscription id to client, @@ -4026,16 +3981,15 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveInvalidSubscr TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveUnsolicitedReportMessageWithInvalidSubscriptionId) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); chip::app::AttributePathParams attributePathParams[2]; readPrepareParams.mpAttributePathParamsList = attributePathParams; @@ -4053,13 +4007,13 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveUnsolicitedRe readPrepareParams.mMaxIntervalCeilingSeconds = 5; { - mpTestContext->GetLoopback().mSentMessageCount = 0; - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + GetLoopback().mSentMessageCount = 0; + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 5u); + DrainAndServiceIO(); + EXPECT_EQ(GetLoopback().mSentMessageCount, 5u); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); ASSERT_NE(engine->ActiveHandlerAt(0), nullptr); delegate.mpReadHandler = engine->ActiveHandlerAt(0); @@ -4075,8 +4029,8 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveUnsolicitedRe EXPECT_EQ(writer.Finalize(&msgBuf), CHIP_NO_ERROR); - mpTestContext->GetLoopback().mSentMessageCount = 0; - auto exchange = InteractionModelEngine::GetInstance()->GetExchangeManager()->NewContext( + GetLoopback().mSentMessageCount = 0; + auto exchange = InteractionModelEngine::GetInstance()->GetExchangeManager()->NewContext( delegate.mpReadHandler->mSessionHandle.Get().Value(), delegate.mpReadHandler); delegate.mpReadHandler->mExchangeCtx.Grab(exchange); @@ -4085,13 +4039,13 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveUnsolicitedRe std::move(msgBuf), Messaging::SendMessageFlags::kExpectResponse), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // The server sends a data report. // The client receives the data report data and sends out status report with invalid subsciption. // The server should respond with a status report of its own, leading to 4 messages (because // the client would ack the server's status report), just sends an ack to the status report it got. - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 3u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 3u); } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); @@ -4103,7 +4057,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeClientReceiveUnsolicitedRe TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadChunkingInvalidSubscriptionId) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -4111,8 +4065,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadChunkingInvalidSubscriptionId) MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); EXPECT_FALSE(delegate.mGotEventResponse); chip::app::AttributePathParams attributePathParams[1]; @@ -4121,24 +4074,24 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadChunkingInvalidSubscriptionId) attributePathParams[0].mClusterId = chip::Test::MockClusterId(2); attributePathParams[0].mAttributeId = chip::Test::MockAttributeId(4); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpEventPathParamsList = nullptr; readPrepareParams.mEventPathParamsListSize = 0; readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mAttributePathParamsListSize = 1; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 3; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 3; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes); EXPECT_FALSE(msgBuf.IsNull()); @@ -4157,36 +4110,36 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadChunkingInvalidSubscriptionId) // Since we are dropping packets, things are not getting acked. Set up // our MRP state to look like what it would have looked like if the // packet had not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, readClient.mExchange.Get()); + PretendWeGotReplyFromServer(*this, readClient.mExchange.Get()); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 4u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 4u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); ASSERT_NE(engine->ActiveHandlerAt(0), nullptr); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; readClient.OnMessageReceived(readClient.mExchange.Get(), payloadHeader, std::move(msgBuf)); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // TODO: Need to validate what status is being sent to the ReadHandler // The ReadHandler's exchange is still open when we synthesize the report data message. // Since we synthesized the second report data message to the ReadClient with invalid subscription id, instead of // sending it from the ReadHandler, the only messages here are the ReadClient's StatusResponse to the unexpected message // and an MRP ack. - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); EXPECT_EQ(delegate.mError, CHIP_ERROR_INVALID_SUBSCRIPTION); } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // Read Client sends a malformed subscribe request, interaction model engine fails to parse the request and generates a status @@ -4194,19 +4147,18 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadChunkingInvalidSubscriptionId) TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandlerMalformedSubscribeRequest) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); System::PacketBufferHandle msgBuf; @@ -4226,12 +4178,12 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandlerMalformedSubscribeReques Messaging::SendFlags(Messaging::SendMessageFlags::kExpectResponse)), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mError, CHIP_IM_GLOBAL_STATUS(InvalidAction)); } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // Read Client sends a malformed read request, interaction model engine fails to parse the request and generates a status report @@ -4239,19 +4191,18 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandlerMalformedSubscribeReques TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandlerMalformedReadRequest1) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); System::PacketBufferHandle msgBuf; @@ -4269,12 +4220,12 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandlerMalformedReadRequest1) EXPECT_EQ(readClient.mExchange->SendMessage(Protocols::InteractionModel::MsgType::ReadRequest, std::move(msgBuf), Messaging::SendFlags(Messaging::SendMessageFlags::kExpectResponse)), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mError, CHIP_IM_GLOBAL_STATUS(InvalidAction)); } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // Read Client sends a malformed read request, read handler fails to parse the request and generates a status report to client, @@ -4282,19 +4233,18 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandlerMalformedReadRequest1) TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandlerMalformedReadRequest2) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Read); System::PacketBufferHandle msgBuf; @@ -4312,13 +4262,13 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandlerMalformedReadRequest2) EXPECT_EQ(readClient.mExchange->SendMessage(Protocols::InteractionModel::MsgType::ReadRequest, std::move(msgBuf), Messaging::SendFlags(Messaging::SendMessageFlags::kExpectResponse)), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); ChipLogError(DataManagement, "The error is %s", ErrorStr(delegate.mError)); EXPECT_EQ(delegate.mError, CHIP_IM_GLOBAL_STATUS(InvalidAction)); } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // Read Client creates a subscription with the server, server sends chunked reports, after the handler sends out the first @@ -4326,14 +4276,13 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandlerMalformedReadRequest2) TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeSendUnknownMessage) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); chip::app::AttributePathParams attributePathParams[1]; // Mock Attribute 4 is a big attribute, with 6 large OCTET_STRING @@ -4341,34 +4290,34 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeSendUnknownMessage) attributePathParams[0].mClusterId = chip::Test::MockClusterId(2); attributePathParams[0].mAttributeId = chip::Test::MockAttributeId(4); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mAttributePathParamsListSize = 1; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 1; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 1; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Since we are dropping packets, things are not getting acked. Set up // our MRP state to look like what it would have looked like if the // packet had not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, readClient.mExchange.Get()); + PretendWeGotReplyFromServer(*this, readClient.mExchange.Get()); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); ASSERT_NE(engine->ActiveHandlerAt(0), nullptr); - mpTestContext->GetLoopback().mSentMessageCount = 0; + GetLoopback().mSentMessageCount = 0; // Server sends out status report, client should send status report along with Piggybacking ack, but we don't do that // Instead, we send out unknown message to server @@ -4381,19 +4330,19 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeSendUnknownMessage) writer.Finalize(&msgBuf); readClient.mExchange->SendMessage(Protocols::InteractionModel::MsgType::WriteRequest, std::move(msgBuf)); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // client sends invalid write request, server sends out status report with invalid action and closes, client replies // with status report server replies with MRP Ack - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 4u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 4u); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 0u); } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // Read Client creates a subscription with the server, server sends chunked reports, after the handler sends out invalid status @@ -4401,14 +4350,13 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeSendUnknownMessage) TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeSendInvalidStatusReport) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); chip::app::AttributePathParams attributePathParams[1]; // Mock Attribute 4 is a big attribute, with 6 large OCTET_STRING @@ -4416,30 +4364,30 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeSendInvalidStatusReport) attributePathParams[0].mClusterId = chip::Test::MockClusterId(2); attributePathParams[0].mAttributeId = chip::Test::MockAttributeId(4); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mAttributePathParamsListSize = 1; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 1; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 1; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Since we are dropping packets, things are not getting acked. Set up // our MRP state to look like what it would have looked like if the // packet had not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, readClient.mExchange.Get()); + PretendWeGotReplyFromServer(*this, readClient.mExchange.Get()); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); - mpTestContext->GetLoopback().mSentMessageCount = 0; + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); + GetLoopback().mSentMessageCount = 0; EXPECT_EQ(engine->GetNumActiveReadHandlers(), 1u); ASSERT_NE(engine->ActiveHandlerAt(0), nullptr); @@ -4452,20 +4400,20 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeSendInvalidStatusReport) writer.Finalize(&msgBuf); readClient.mExchange->SendMessage(Protocols::InteractionModel::MsgType::StatusResponse, std::move(msgBuf)); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // client sends malformed status response, server sends out status report with invalid action and close, client replies // with status report server replies with MRP Ack - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 4u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 4u); EXPECT_EQ(engine->GetNumActiveReadHandlers(), 0u); } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // Read Client sends a malformed subscribe request, the server fails to parse the request and generates a status report to the @@ -4473,19 +4421,18 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscribeSendInvalidStatusReport) TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandlerInvalidSubscribeRequest) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); System::PacketBufferHandle msgBuf; @@ -4503,12 +4450,12 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandlerInvalidSubscribeRequest) EXPECT_EQ(readClient.mExchange->SendMessage(Protocols::InteractionModel::MsgType::SubscribeRequest, std::move(msgBuf), Messaging::SendFlags(Messaging::SendMessageFlags::kExpectResponse)), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mError, CHIP_IM_GLOBAL_STATUS(InvalidAction)); } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // Create the subscription, then remove the corresponding fabric in client and handler, the corresponding @@ -4516,7 +4463,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandlerInvalidSubscribeRequest) TEST_F(TestReadInteraction, TestSubscribeInvalidateFabric) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -4524,10 +4471,9 @@ TEST_F(TestReadInteraction, TestSubscribeInvalidateFabric) MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpAttributePathParamsList = new chip::app::AttributePathParams[1]; readPrepareParams.mAttributePathParamsListSize = 1; @@ -4539,40 +4485,40 @@ TEST_F(TestReadInteraction, TestSubscribeInvalidateFabric) readPrepareParams.mMaxIntervalCeilingSeconds = 0; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); delegate.mGotReport = false; EXPECT_EQ(readClient.SendAutoResubscribeRequest(std::move(readPrepareParams)), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); EXPECT_EQ(engine->GetNumActiveReadHandlers(ReadHandler::InteractionType::Subscribe), 1u); ASSERT_NE(engine->ActiveHandlerAt(0), nullptr); delegate.mpReadHandler = engine->ActiveHandlerAt(0); - mpTestContext->GetFabricTable().Delete(mpTestContext->GetAliceFabricIndex()); + GetFabricTable().Delete(GetAliceFabricIndex()); EXPECT_EQ(engine->GetNumActiveReadHandlers(ReadHandler::InteractionType::Subscribe), 0u); - mpTestContext->GetFabricTable().Delete(mpTestContext->GetBobFabricIndex()); + GetFabricTable().Delete(GetBobFabricIndex()); EXPECT_EQ(delegate.mError, CHIP_ERROR_IM_FABRIC_DELETED); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateAliceFabric(); - mpTestContext->CreateBobFabric(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateAliceFabric(); + CreateBobFabric(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); engine->Shutdown(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F_FROM_FIXTURE(TestReadInteraction, TestShutdownSubscription) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -4580,10 +4526,9 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestShutdownSubscription) MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpAttributePathParamsList = new chip::app::AttributePathParams[1]; readPrepareParams.mAttributePathParamsListSize = 1; @@ -4595,14 +4540,14 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestShutdownSubscription) readPrepareParams.mMaxIntervalCeilingSeconds = 0; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); delegate.mGotReport = false; EXPECT_EQ(readClient.SendAutoResubscribeRequest(std::move(readPrepareParams)), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); EXPECT_EQ(engine->GetNumActiveReadHandlers(ReadHandler::InteractionType::Subscribe), 1u); @@ -4613,7 +4558,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestShutdownSubscription) } engine->Shutdown(); EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } /** @@ -4624,18 +4569,17 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestShutdownSubscription) TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscriptionReportWithDefunctSession) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); MockInteractionModelApp delegate; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), gReportScheduler), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), gReportScheduler), CHIP_NO_ERROR); AttributePathParams subscribePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2), chip::Test::MockAttributeId(1)); - ReadPrepareParams readPrepareParams(mpTestContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mpAttributePathParamsList = &subscribePath; readPrepareParams.mAttributePathParamsListSize = 1; @@ -4643,14 +4587,14 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscriptionReportWithDefunctSessio readPrepareParams.mMaxIntervalCeilingSeconds = 0; { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpTestContext->GetExchangeManager(), delegate, + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, chip::app::ReadClient::InteractionType::Subscribe); delegate.mGotReport = false; EXPECT_EQ(readClient.SendSubscribeRequest(std::move(readPrepareParams)), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); EXPECT_EQ(delegate.mNumAttributeResponse, 1); @@ -4663,13 +4607,13 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscriptionReportWithDefunctSessio // Verify that the session we will reset later is the one we will mess // with now. - EXPECT_EQ(SessionHandle(*readHandler->GetSession()), mpTestContext->GetSessionAliceToBob()); + EXPECT_EQ(SessionHandle(*readHandler->GetSession()), GetSessionAliceToBob()); // Test that we send reports as needed. delegate.mGotReport = false; delegate.mNumAttributeResponse = 0; engine->GetReportingEngine().SetDirty(subscribePath); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mGotReport); EXPECT_EQ(delegate.mNumAttributeResponse, 1); @@ -4684,7 +4628,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscriptionReportWithDefunctSessio delegate.mNumAttributeResponse = 0; engine->GetReportingEngine().SetDirty(subscribePath); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_FALSE(delegate.mGotReport); EXPECT_EQ(delegate.mNumAttributeResponse, 0); @@ -4694,11 +4638,11 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestSubscriptionReportWithDefunctSessio } engine->Shutdown(); EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); // Get rid of our defunct session. - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->CreateSessionAliceToBob(); + ExpireSessionAliceToBob(); + CreateSessionAliceToBob(); } } // namespace app diff --git a/src/app/tests/TestReportScheduler.cpp b/src/app/tests/TestReportScheduler.cpp index dc54395149bbe4..bd8cd11041dacf 100644 --- a/src/app/tests/TestReportScheduler.cpp +++ b/src/app/tests/TestReportScheduler.cpp @@ -26,8 +26,6 @@ #include namespace { -using TestContext = chip::Test::AppContext; - class NullReadHandlerCallback : public chip::app::ReadHandler::ManagementCallback { public: @@ -52,39 +50,9 @@ using Milliseconds64 = System::Clock::Milliseconds64; static const size_t kNumMaxReadHandlers = 16; -class TestReportScheduler : public ::testing::Test +class TestReportScheduler : public chip::Test::AppContext { public: - static void SetUpTestSuite() - { - mpTestContext = new chip::Test::AppContext; - mpTestContext->SetUpTestSuite(); - } - static void TearDownTestSuite() - { - mpTestContext->TearDownTestSuite(); - if (mpTestContext != nullptr) - { - delete mpTestContext; - } - } - - void SetUp() override - { - - if (mpTestContext != nullptr) - { - mpTestContext->SetUp(); - } - } - void TearDown() override - { - if (mpTestContext != nullptr) - { - mpTestContext->TearDown(); - } - } - void TestReadHandlerList(); void TestReportTiming(); void TestObserverCallbacks(); @@ -125,12 +93,8 @@ class TestReportScheduler : public ::testing::Test return ret; } - - static chip::Test::AppContext * mpTestContext; }; -chip::Test::AppContext * TestReportScheduler::mpTestContext = nullptr; - class TestTimerDelegate : public ReportScheduler::TimerDelegate { public: @@ -300,7 +264,7 @@ TEST_F_FROM_FIXTURE(TestReportScheduler, TestReadHandlerList) NullReadHandlerCallback nullCallback; // exchange context - Messaging::ExchangeContext * exchangeCtx = mpTestContext->NewExchangeToAlice(nullptr, false); + Messaging::ExchangeContext * exchangeCtx = NewExchangeToAlice(nullptr, false); // Read handler pool ObjectPool readHandlerPool; @@ -319,7 +283,7 @@ TEST_F_FROM_FIXTURE(TestReportScheduler, TestReadHandlerList) EXPECT_EQ(readHandlerPool.Allocated(), kNumMaxReadHandlers); EXPECT_EQ(sScheduler.GetNumReadHandlers(), kNumMaxReadHandlers); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 1u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 1u); // Test unregister first ReadHandler uint32_t target = 0; @@ -356,7 +320,7 @@ TEST_F_FROM_FIXTURE(TestReportScheduler, TestReadHandlerList) readHandlerPool.ReleaseAll(); exchangeCtx->Close(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F_FROM_FIXTURE(TestReportScheduler, TestReportTiming) @@ -364,7 +328,7 @@ TEST_F_FROM_FIXTURE(TestReportScheduler, TestReportTiming) NullReadHandlerCallback nullCallback; // exchange context - Messaging::ExchangeContext * exchangeCtx = mpTestContext->NewExchangeToAlice(nullptr, false); + Messaging::ExchangeContext * exchangeCtx = NewExchangeToAlice(nullptr, false); // Read handler pool ObjectPool readHandlerPool; @@ -424,7 +388,7 @@ TEST_F_FROM_FIXTURE(TestReportScheduler, TestReportTiming) sScheduler.UnregisterAllHandlers(); readHandlerPool.ReleaseAll(); exchangeCtx->Close(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F_FROM_FIXTURE(TestReportScheduler, TestObserverCallbacks) @@ -432,7 +396,7 @@ TEST_F_FROM_FIXTURE(TestReportScheduler, TestObserverCallbacks) NullReadHandlerCallback nullCallback; // exchange context - Messaging::ExchangeContext * exchangeCtx = mpTestContext->NewExchangeToAlice(nullptr, false); + Messaging::ExchangeContext * exchangeCtx = NewExchangeToAlice(nullptr, false); // Read handler pool ObjectPool readHandlerPool; @@ -499,7 +463,7 @@ TEST_F_FROM_FIXTURE(TestReportScheduler, TestObserverCallbacks) readHandlerPool.ReleaseAll(); exchangeCtx->Close(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F_FROM_FIXTURE(TestReportScheduler, TestSynchronizedScheduler) @@ -507,7 +471,7 @@ TEST_F_FROM_FIXTURE(TestReportScheduler, TestSynchronizedScheduler) NullReadHandlerCallback nullCallback; // exchange context - Messaging::ExchangeContext * exchangeCtx = mpTestContext->NewExchangeToAlice(nullptr, false); + Messaging::ExchangeContext * exchangeCtx = NewExchangeToAlice(nullptr, false); // First test: ReadHandler 2 merge on ReadHandler 1 max interval // Read handler pool @@ -839,7 +803,7 @@ TEST_F_FROM_FIXTURE(TestReportScheduler, TestSynchronizedScheduler) syncScheduler.UnregisterAllHandlers(); readHandlerPool.ReleaseAll(); exchangeCtx->Close(); - EXPECT_EQ(mpTestContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } } // namespace reporting diff --git a/src/app/tests/TestReportingEngine.cpp b/src/app/tests/TestReportingEngine.cpp index 97d179b4e72dcc..341428fb7118d9 100644 --- a/src/app/tests/TestReportingEngine.cpp +++ b/src/app/tests/TestReportingEngine.cpp @@ -39,8 +39,6 @@ #include #include -using TestContext = chip::Test::AppContext; - namespace chip { constexpr ClusterId kTestClusterId = 6; @@ -51,26 +49,9 @@ constexpr chip::AttributeId kTestFieldId2 = 2; namespace app { namespace reporting { -std::unique_ptr mpTestContext; - -class TestReportingEngine : public ::testing::Test +class TestReportingEngine : public chip::Test::AppContext { public: - static void SetUpTestSuite() - { - - mpTestContext = std::make_unique(); - ASSERT_NE(mpTestContext, nullptr); - mpTestContext->SetUpTestSuite(); - } - static void TearDownTestSuite() - { - mpTestContext->TearDownTestSuite(); - mpTestContext.reset(); - } - void SetUp() { mpTestContext->SetUp(); } - void TearDown() { mpTestContext->TearDown(); } - template static bool VerifyDirtySetContent(const Args &... args); static bool InsertToDirtySet(const AttributePathParams & aPath); @@ -161,11 +142,11 @@ TEST_F_FROM_FIXTURE(TestReportingEngine, TestBuildAndSendSingleReportData) ReadRequestMessage::Builder readRequestBuilder; DummyDelegate dummy; - EXPECT_EQ(InteractionModelEngine::GetInstance()->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), + EXPECT_EQ(InteractionModelEngine::GetInstance()->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); TestExchangeDelegate delegate; - Messaging::ExchangeContext * exchangeCtx = mpTestContext->NewExchangeToAlice(&delegate); + Messaging::ExchangeContext * exchangeCtx = NewExchangeToAlice(&delegate); writer.Init(std::move(readRequestbuf)); EXPECT_EQ(readRequestBuilder.Init(&writer), CHIP_NO_ERROR); @@ -193,12 +174,12 @@ TEST_F_FROM_FIXTURE(TestReportingEngine, TestBuildAndSendSingleReportData) EXPECT_EQ(InteractionModelEngine::GetInstance()->GetReportingEngine().BuildAndSendSingleReportData(&readHandler), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); } TEST_F_FROM_FIXTURE(TestReportingEngine, TestMergeOverlappedAttributePath) { - EXPECT_EQ(InteractionModelEngine::GetInstance()->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), + EXPECT_EQ(InteractionModelEngine::GetInstance()->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); @@ -253,7 +234,7 @@ TEST_F_FROM_FIXTURE(TestReportingEngine, TestMergeOverlappedAttributePath) TEST_F_FROM_FIXTURE(TestReportingEngine, TestMergeAttributePathWhenDirtySetPoolExhausted) { - EXPECT_EQ(InteractionModelEngine::GetInstance()->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), + EXPECT_EQ(InteractionModelEngine::GetInstance()->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); diff --git a/src/app/tests/TestTimedHandler.cpp b/src/app/tests/TestTimedHandler.cpp index 8b6aadbf92325a..42748a0ee4d50a 100644 --- a/src/app/tests/TestTimedHandler.cpp +++ b/src/app/tests/TestTimedHandler.cpp @@ -29,8 +29,6 @@ #include #include -using TestContext = chip::Test::AppContext; - namespace chip { namespace app { @@ -39,33 +37,14 @@ using namespace Protocols::InteractionModel; namespace { -class TestTimedHandler : public ::testing::Test +class TestTimedHandler : public chip::Test::AppContext { public: - static void SetUpTestSuite() - { - - mpTestContext = new TestContext; - mpTestContext->SetUpTestSuite(); - } - static void TearDownTestSuite() - { - mpTestContext->TearDownTestSuite(); - delete mpTestContext; - } - - void SetUp() override { mpTestContext->SetUp(); } - void TearDown() override { mpTestContext->TearDown(); } - - static TestContext * mpTestContext; - - static void TestFollowingMessageFastEnough(MsgType aMsgType); - static void TestFollowingMessageTooSlow(MsgType aMsgType); - static void GenerateTimedRequest(uint16_t aTimeoutValue, System::PacketBufferHandle & aPayload); + void TestFollowingMessageFastEnough(MsgType aMsgType); + void TestFollowingMessageTooSlow(MsgType aMsgType); + void GenerateTimedRequest(uint16_t aTimeoutValue, System::PacketBufferHandle & aPayload); }; -TestContext * TestTimedHandler::mpTestContext = nullptr; - class TestExchangeDelegate : public Messaging::ExchangeDelegate { CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * aExchangeContext, const PayloadHeader & aPayloadHeader, @@ -124,7 +103,7 @@ void TestTimedHandler::TestFollowingMessageFastEnough(MsgType aMsgType) GenerateTimedRequest(500, payload); TestExchangeDelegate delegate; - ExchangeContext * exchange = mpTestContext->NewExchangeToAlice(&delegate); + ExchangeContext * exchange = NewExchangeToAlice(&delegate); ASSERT_NE(exchange, nullptr); EXPECT_FALSE(delegate.mNewMessageReceived); @@ -133,7 +112,7 @@ void TestTimedHandler::TestFollowingMessageFastEnough(MsgType aMsgType) EXPECT_EQ(exchange->SendMessage(MsgType::TimedRequest, std::move(payload), SendMessageFlags::kExpectResponse), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mNewMessageReceived); EXPECT_TRUE(delegate.mLastMessageWasStatus); EXPECT_EQ(delegate.mError, CHIP_NO_ERROR); @@ -148,7 +127,7 @@ void TestTimedHandler::TestFollowingMessageFastEnough(MsgType aMsgType) EXPECT_EQ(exchange->SendMessage(aMsgType, std::move(payload), SendMessageFlags::kExpectResponse), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mNewMessageReceived); EXPECT_TRUE(delegate.mLastMessageWasStatus); EXPECT_NE(StatusIB(delegate.mError).mStatus, Status::Timeout); @@ -156,7 +135,7 @@ void TestTimedHandler::TestFollowingMessageFastEnough(MsgType aMsgType) TEST_F(TestTimedHandler, TestInvokeFastEnough) { - TestTimedHandler::TestFollowingMessageFastEnough(MsgType::InvokeCommandRequest); + TestFollowingMessageFastEnough(MsgType::InvokeCommandRequest); } TEST_F(TestTimedHandler, TestWriteFastEnough) @@ -171,7 +150,7 @@ void TestTimedHandler::TestFollowingMessageTooSlow(MsgType aMsgType) GenerateTimedRequest(50, payload); TestExchangeDelegate delegate; - ExchangeContext * exchange = mpTestContext->NewExchangeToAlice(&delegate); + ExchangeContext * exchange = NewExchangeToAlice(&delegate); ASSERT_NE(exchange, nullptr); EXPECT_FALSE(delegate.mNewMessageReceived); @@ -180,7 +159,7 @@ void TestTimedHandler::TestFollowingMessageTooSlow(MsgType aMsgType) EXPECT_EQ(exchange->SendMessage(MsgType::TimedRequest, std::move(payload), SendMessageFlags::kExpectResponse), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mNewMessageReceived); EXPECT_TRUE(delegate.mLastMessageWasStatus); EXPECT_EQ(delegate.mError, CHIP_NO_ERROR); @@ -198,7 +177,7 @@ void TestTimedHandler::TestFollowingMessageTooSlow(MsgType aMsgType) EXPECT_EQ(exchange->SendMessage(aMsgType, std::move(payload), SendMessageFlags::kExpectResponse), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mNewMessageReceived); EXPECT_TRUE(delegate.mLastMessageWasStatus); EXPECT_EQ(StatusIB(delegate.mError).mStatus, Status::Timeout); @@ -222,14 +201,14 @@ TEST_F(TestTimedHandler, TestInvokeNeverComes) GenerateTimedRequest(50, payload); TestExchangeDelegate delegate; - ExchangeContext * exchange = mpTestContext->NewExchangeToAlice(&delegate); + ExchangeContext * exchange = NewExchangeToAlice(&delegate); ASSERT_NE(exchange, nullptr); EXPECT_FALSE(delegate.mNewMessageReceived); EXPECT_EQ(exchange->SendMessage(MsgType::TimedRequest, std::move(payload), SendMessageFlags::kExpectResponse), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(delegate.mNewMessageReceived); EXPECT_TRUE(delegate.mLastMessageWasStatus); EXPECT_EQ(delegate.mError, CHIP_NO_ERROR); diff --git a/src/app/tests/TestWriteInteraction.cpp b/src/app/tests/TestWriteInteraction.cpp index 65f7c415a65550..625d6c3328d2f2 100644 --- a/src/app/tests/TestWriteInteraction.cpp +++ b/src/app/tests/TestWriteInteraction.cpp @@ -49,30 +49,16 @@ chip::TestPersistentStorageDelegate gTestStorage; chip::Crypto::DefaultSessionKeystore gSessionKeystore; chip::Credentials::GroupDataProviderImpl gGroupsProvider(kMaxGroupsPerFabric, kMaxGroupKeysPerFabric); -using TestContext = chip::Test::AppContext; - } // namespace namespace chip { namespace app { -class TestWriteInteraction : public ::testing::Test +class TestWriteInteraction : public chip::Test::AppContext { public: - static void SetUpTestSuite() - { - mpTestContext = new TestContext; - mpTestContext->SetUpTestSuite(); - } - - static void TearDownTestSuite() - { - mpTestContext->TearDownTestSuite(); - delete mpTestContext; - } void SetUp() override { - - mpTestContext->SetUp(); + AppContext::SetUp(); gTestStorage.ClearStorage(); gGroupsProvider.SetStorageDelegate(&gTestStorage); @@ -82,8 +68,8 @@ class TestWriteInteraction : public ::testing::Test uint8_t buf[sizeof(chip::CompressedFabricId)]; chip::MutableByteSpan span(buf); - ASSERT_EQ(mpTestContext->GetBobFabric()->GetCompressedFabricIdBytes(span), CHIP_NO_ERROR); - ASSERT_EQ(chip::GroupTesting::InitData(&gGroupsProvider, mpTestContext->GetBobFabricIndex(), span), CHIP_NO_ERROR); + ASSERT_EQ(GetBobFabric()->GetCompressedFabricIdBytes(span), CHIP_NO_ERROR); + ASSERT_EQ(chip::GroupTesting::InitData(&gGroupsProvider, GetBobFabricIndex(), span), CHIP_NO_ERROR); } void TearDown() override { @@ -92,11 +78,9 @@ class TestWriteInteraction : public ::testing::Test { provider->Finish(); } - mpTestContext->TearDown(); + AppContext::TearDown(); } - static TestContext * mpTestContext; - void TestWriteClient(); void TestWriteClientGroup(); void TestWriteHandlerReceiveInvalidMessage(); @@ -111,8 +95,6 @@ class TestWriteInteraction : public ::testing::Test static void GenerateWriteResponse(System::PacketBufferHandle & aPayload); }; -TestContext * TestWriteInteraction::mpTestContext = nullptr; - class TestExchangeDelegate : public Messaging::ExchangeDelegate { CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader, @@ -261,14 +243,14 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteClient) { TestWriteClientCallback callback; - app::WriteClient writeClient(&mpTestContext->GetExchangeManager(), &callback, /* aTimedWriteTimeoutMs = */ NullOptional); + app::WriteClient writeClient(&GetExchangeManager(), &callback, /* aTimedWriteTimeoutMs = */ NullOptional); System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); AddAttributeDataIB(writeClient); - EXPECT_EQ(writeClient.SendWriteRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(writeClient.SendWriteRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); GenerateWriteResponse(buf); @@ -276,7 +258,7 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteClient) writeClient.Close(); - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); EXPECT_EQ(rm->TestGetCountRetransTable(), 0); } @@ -284,17 +266,17 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteClientGroup) { TestWriteClientCallback callback; - app::WriteClient writeClient(&mpTestContext->GetExchangeManager(), &callback, /* aTimedWriteTimeoutMs = */ NullOptional); + app::WriteClient writeClient(&GetExchangeManager(), &callback, /* aTimedWriteTimeoutMs = */ NullOptional); System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); AddAttributeDataIB(writeClient); - SessionHandle groupSession = mpTestContext->GetSessionBobToFriends(); + SessionHandle groupSession = GetSessionBobToFriends(); EXPECT_TRUE(groupSession->IsGroupSession()); EXPECT_EQ(writeClient.SendWriteRequest(groupSession), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); // The WriteClient should be shutdown once we SendWriteRequest for group. EXPECT_EQ(writeClient.mState, WriteClient::State::AwaitingDestruction); @@ -319,7 +301,7 @@ TEST_F(TestWriteInteraction, TestWriteHandler) GenerateWriteRequest(messageIsTimed, buf); TestExchangeDelegate delegate; - Messaging::ExchangeContext * exchange = mpTestContext->NewExchangeToBob(&delegate); + Messaging::ExchangeContext * exchange = NewExchangeToBob(&delegate); Status status = writeHandler.OnWriteRequest(exchange, std::move(buf), transactionIsTimed); if (messageIsTimed == transactionIsTimed) @@ -331,9 +313,9 @@ TEST_F(TestWriteInteraction, TestWriteHandler) EXPECT_EQ(status, Status::TimedRequestMismatch); } - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); EXPECT_EQ(rm->TestGetCountRetransTable(), 0); } } @@ -342,15 +324,13 @@ TEST_F(TestWriteInteraction, TestWriteHandler) TEST_F(TestWriteInteraction, TestWriteRoundtripWithClusterObjects) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); TestWriteClientCallback callback; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler()), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); app::WriteClient writeClient(engine->GetExchangeManager(), &callback, Optional::Missing()); @@ -375,9 +355,9 @@ TEST_F(TestWriteInteraction, TestWriteRoundtripWithClusterObjects) EXPECT_EQ(callback.mOnSuccessCalled, 0); - EXPECT_EQ(writeClient.SendWriteRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(writeClient.SendWriteRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(callback.mOnSuccessCalled, 1); @@ -408,15 +388,13 @@ TEST_F(TestWriteInteraction, TestWriteRoundtripWithClusterObjects) TEST_F(TestWriteInteraction, TestWriteRoundtripWithClusterObjectsVersionMatch) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); TestWriteClientCallback callback; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler()), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); app::WriteClient writeClient(engine->GetExchangeManager(), &callback, Optional::Missing()); @@ -435,9 +413,9 @@ TEST_F(TestWriteInteraction, TestWriteRoundtripWithClusterObjectsVersionMatch) EXPECT_EQ(callback.mOnSuccessCalled, 0); - EXPECT_EQ(writeClient.SendWriteRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(writeClient.SendWriteRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(callback.mOnSuccessCalled, 1); EXPECT_EQ(callback.mOnErrorCalled, 0); @@ -454,15 +432,13 @@ TEST_F(TestWriteInteraction, TestWriteRoundtripWithClusterObjectsVersionMatch) TEST_F(TestWriteInteraction, TestWriteRoundtripWithClusterObjectsVersionMismatch) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); TestWriteClientCallback callback; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler()), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); app::WriteClient writeClient(engine->GetExchangeManager(), &callback, Optional::Missing()); @@ -484,9 +460,9 @@ TEST_F(TestWriteInteraction, TestWriteRoundtripWithClusterObjectsVersionMismatch EXPECT_EQ(callback.mOnSuccessCalled, 0); - EXPECT_EQ(writeClient.SendWriteRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(writeClient.SendWriteRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(callback.mOnSuccessCalled, 1); EXPECT_EQ(callback.mOnErrorCalled, 0); @@ -503,15 +479,13 @@ TEST_F(TestWriteInteraction, TestWriteRoundtripWithClusterObjectsVersionMismatch TEST_F(TestWriteInteraction, TestWriteRoundtrip) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); TestWriteClientCallback callback; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler()), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); app::WriteClient writeClient(engine->GetExchangeManager(), &callback, Optional::Missing()); @@ -522,9 +496,9 @@ TEST_F(TestWriteInteraction, TestWriteRoundtrip) EXPECT_EQ(callback.mOnErrorCalled, 0); EXPECT_EQ(callback.mOnDoneCalled, 0); - EXPECT_EQ(writeClient.SendWriteRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); + EXPECT_EQ(writeClient.SendWriteRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(callback.mOnSuccessCalled, 1); EXPECT_EQ(callback.mOnErrorCalled, 0); @@ -541,37 +515,35 @@ TEST_F(TestWriteInteraction, TestWriteRoundtrip) #if CONFIG_BUILD_FOR_HOST_UNIT_TEST TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteHandlerReceiveInvalidMessage) { - auto sessionHandle = mpTestContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); app::AttributePathParams attributePath(2, 3, 4); - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); TestWriteClientCallback writeCallback; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler()), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); // Reserve all except the last 128 bytes, so that we make sure to chunk. - app::WriteClient writeClient(&mpTestContext->GetExchangeManager(), &writeCallback, Optional::Missing(), + app::WriteClient writeClient(&GetExchangeManager(), &writeCallback, Optional::Missing(), static_cast(kMaxSecureSduLengthBytes - 128) /* reserved buffer size */); ByteSpan list[5]; EXPECT_EQ(writeClient.EncodeAttribute(attributePath, app::DataModel::List(list, 5)), CHIP_NO_ERROR); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 2; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 2; EXPECT_EQ(writeClient.SendWriteRequest(sessionHandle), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(InteractionModelEngine::GetInstance()->GetNumActiveWriteHandlers(), 1u); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 3u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 3u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes); EXPECT_FALSE(msgBuf.IsNull()); @@ -590,65 +562,63 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteHandlerReceiveInvalidMessage) rm->ClearRetransTable(writeClient.mExchangeCtx.Get()); rm->ClearRetransTable(writeHandler->mExchangeCtx.Get()); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; writeHandler->OnMessageReceived(writeHandler->mExchangeCtx.Get(), payloadHeader, std::move(msgBuf)); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(writeCallback.mLastErrorReason.mStatus, Protocols::InteractionModel::Status::InvalidAction); EXPECT_EQ(InteractionModelEngine::GetInstance()->GetNumActiveWriteHandlers(), 0u); engine->Shutdown(); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // This test is to create Chunked write requests, we drop the message since the 3rd message, then remove fabrics for client and // handler, the corresponding client and handler would be released as well. TEST_F(TestWriteInteraction, TestWriteHandlerInvalidateFabric) { - auto sessionHandle = mpTestContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); app::AttributePathParams attributePath(2, 3, 4); - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); TestWriteClientCallback writeCallback; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler()), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); // Reserve all except the last 128 bytes, so that we make sure to chunk. - app::WriteClient writeClient(&mpTestContext->GetExchangeManager(), &writeCallback, Optional::Missing(), + app::WriteClient writeClient(&GetExchangeManager(), &writeCallback, Optional::Missing(), static_cast(kMaxSecureSduLengthBytes - 128) /* reserved buffer size */); ByteSpan list[5]; EXPECT_EQ(writeClient.EncodeAttribute(attributePath, app::DataModel::List(list, 5)), CHIP_NO_ERROR); - mpTestContext->GetLoopback().mDroppedMessageCount = 0; - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 2; + GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 2; EXPECT_EQ(writeClient.SendWriteRequest(sessionHandle), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(InteractionModelEngine::GetInstance()->GetNumActiveWriteHandlers(), 1u); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 3u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 3u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); - mpTestContext->GetFabricTable().Delete(mpTestContext->GetAliceFabricIndex()); + GetFabricTable().Delete(GetAliceFabricIndex()); EXPECT_EQ(InteractionModelEngine::GetInstance()->GetNumActiveWriteHandlers(), 0u); engine->Shutdown(); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateAliceFabric(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateAliceFabric(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } #endif @@ -657,15 +627,13 @@ TEST_F(TestWriteInteraction, TestWriteHandlerInvalidateFabric) TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage1) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); TestWriteClientCallback callback; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler()), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); app::WriteClient writeClient(engine->GetExchangeManager(), &callback, Optional::Missing()); @@ -676,15 +644,15 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage1) EXPECT_EQ(callback.mOnErrorCalled, 0); EXPECT_EQ(callback.mOnDoneCalled, 0); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 1; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; - EXPECT_EQ(writeClient.SendWriteRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 1; + GetLoopback().mDroppedMessageCount = 0; + EXPECT_EQ(writeClient.SendWriteRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); + DrainAndServiceIO(); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes); EXPECT_FALSE(msgBuf.IsNull()); @@ -700,15 +668,15 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage1) // Since we are dropping packets, things are not getting acked. Set up // our MRP state to look like what it would have looked like if the // packet had not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, writeClient.mExchangeCtx.Get()); + PretendWeGotReplyFromServer(*this, writeClient.mExchangeCtx.Get()); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(writeClient.OnMessageReceived(writeClient.mExchangeCtx.Get(), payloadHeader, std::move(msgBuf)), CHIP_ERROR_INVALID_MESSAGE_TYPE); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(callback.mError, CHIP_ERROR_INVALID_MESSAGE_TYPE); EXPECT_EQ(callback.mOnSuccessCalled, 0); @@ -717,28 +685,26 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage1) // TODO: Check that the server gets the right status. // Client sents status report with invalid action, server's exchange has been closed, so all it sends is an MRP Ack - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); engine->Shutdown(); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // Write Client sends a write request, receives a malformed write response message, sends a Status Report. TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage2) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); TestWriteClientCallback callback; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler()), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); app::WriteClient writeClient(engine->GetExchangeManager(), &callback, Optional::Missing()); @@ -749,15 +715,15 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage2) EXPECT_EQ(callback.mOnErrorCalled, 0); EXPECT_EQ(callback.mOnDoneCalled, 0); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 1; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; - EXPECT_EQ(writeClient.SendWriteRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 1; + GetLoopback().mDroppedMessageCount = 0; + EXPECT_EQ(writeClient.SendWriteRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); + DrainAndServiceIO(); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes); EXPECT_FALSE(msgBuf.IsNull()); @@ -773,15 +739,15 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage2) // Since we are dropping packets, things are not getting acked. Set up // our MRP state to look like what it would have looked like if the // packet had not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, writeClient.mExchangeCtx.Get()); + PretendWeGotReplyFromServer(*this, writeClient.mExchangeCtx.Get()); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(writeClient.OnMessageReceived(writeClient.mExchangeCtx.Get(), payloadHeader, std::move(msgBuf)), CHIP_ERROR_END_OF_TLV); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(callback.mError, CHIP_ERROR_END_OF_TLV); EXPECT_EQ(callback.mOnSuccessCalled, 0); @@ -789,28 +755,26 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage2) EXPECT_EQ(callback.mOnDoneCalled, 1); // Client sents status report with invalid action, server's exchange has been closed, so all it sends is an MRP Ack - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); engine->Shutdown(); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // Write Client sends a write request, receives a malformed status response message. TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage3) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); TestWriteClientCallback callback; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler()), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); app::WriteClient writeClient(engine->GetExchangeManager(), &callback, Optional::Missing()); @@ -821,15 +785,15 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage3) EXPECT_EQ(callback.mOnErrorCalled, 0); EXPECT_EQ(callback.mOnDoneCalled, 0); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 1; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; - EXPECT_EQ(writeClient.SendWriteRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 1; + GetLoopback().mDroppedMessageCount = 0; + EXPECT_EQ(writeClient.SendWriteRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); + DrainAndServiceIO(); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes); EXPECT_FALSE(msgBuf.IsNull()); @@ -845,15 +809,15 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage3) // Since we are dropping packets, things are not getting acked. Set up // our MRP state to look like what it would have looked like if the // packet had not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, writeClient.mExchangeCtx.Get()); + PretendWeGotReplyFromServer(*this, writeClient.mExchangeCtx.Get()); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(writeClient.OnMessageReceived(writeClient.mExchangeCtx.Get(), payloadHeader, std::move(msgBuf)), CHIP_ERROR_END_OF_TLV); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(callback.mError, CHIP_ERROR_END_OF_TLV); EXPECT_EQ(callback.mOnSuccessCalled, 0); @@ -862,28 +826,26 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage3) // TODO: Check that the server gets the right status // Client sents status report with invalid action, server's exchange has been closed, so all it sends is an MRP ack. - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); engine->Shutdown(); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } // Write Client sends a write request, receives a busy status response message. TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage4) { - Messaging::ReliableMessageMgr * rm = mpTestContext->GetExchangeManager().GetReliableMessageMgr(); + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); TestWriteClientCallback callback; auto * engine = chip::app::InteractionModelEngine::GetInstance(); - EXPECT_EQ(engine->Init(&mpTestContext->GetExchangeManager(), &mpTestContext->GetFabricTable(), - app::reporting::GetDefaultReportScheduler()), - CHIP_NO_ERROR); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); app::WriteClient writeClient(engine->GetExchangeManager(), &callback, Optional::Missing()); @@ -894,15 +856,15 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage4) EXPECT_EQ(callback.mOnErrorCalled, 0); EXPECT_EQ(callback.mOnDoneCalled, 0); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 1; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 1; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; - EXPECT_EQ(writeClient.SendWriteRequest(mpTestContext->GetSessionBobToAlice()), CHIP_NO_ERROR); - mpTestContext->DrainAndServiceIO(); + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 1; + GetLoopback().mNumMessagesToAllowBeforeDropping = 1; + GetLoopback().mDroppedMessageCount = 0; + EXPECT_EQ(writeClient.SendWriteRequest(GetSessionBobToAlice()), CHIP_NO_ERROR); + DrainAndServiceIO(); - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); - EXPECT_EQ(mpTestContext->GetLoopback().mDroppedMessageCount, 1u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u); System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes); EXPECT_FALSE(msgBuf.IsNull()); @@ -919,15 +881,15 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage4) // Since we are dropping packets, things are not getting acked. Set up // our MRP state to look like what it would have looked like if the // packet had not gotten dropped. - PretendWeGotReplyFromServer(*mpTestContext, writeClient.mExchangeCtx.Get()); + PretendWeGotReplyFromServer(*this, writeClient.mExchangeCtx.Get()); - mpTestContext->GetLoopback().mSentMessageCount = 0; - mpTestContext->GetLoopback().mNumMessagesToDrop = 0; - mpTestContext->GetLoopback().mNumMessagesToAllowBeforeDropping = 0; - mpTestContext->GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToAllowBeforeDropping = 0; + GetLoopback().mDroppedMessageCount = 0; EXPECT_EQ(writeClient.OnMessageReceived(writeClient.mExchangeCtx.Get(), payloadHeader, std::move(msgBuf)), CHIP_IM_GLOBAL_STATUS(Busy)); - mpTestContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(callback.mError, CHIP_IM_GLOBAL_STATUS(Busy)); EXPECT_EQ(callback.mOnSuccessCalled, 0); @@ -936,13 +898,13 @@ TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage4) // TODO: Check that the server gets the right status.. // Client sents status report with invalid action, server's exchange has been closed, so it just sends an MRP ack. - EXPECT_EQ(mpTestContext->GetLoopback().mSentMessageCount, 2u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 2u); engine->Shutdown(); - mpTestContext->ExpireSessionAliceToBob(); - mpTestContext->ExpireSessionBobToAlice(); - mpTestContext->CreateSessionAliceToBob(); - mpTestContext->CreateSessionBobToAlice(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); } } // namespace app diff --git a/src/app/tests/suites/certification/Test_TC_OPCREDS_3_3.yaml b/src/app/tests/suites/certification/Test_TC_OPCREDS_3_3.yaml index f7ca4a135ce56d..8c6391cbd2aa14 100644 --- a/src/app/tests/suites/certification/Test_TC_OPCREDS_3_3.yaml +++ b/src/app/tests/suites/certification/Test_TC_OPCREDS_3_3.yaml @@ -35,11 +35,10 @@ tests: disabled: true - label: - "Step 1: Factory Reset DUT (to ensure NOC list is empty at the + "Step 1: Factory Reset TH (to ensure NOC list is empty at the beginning of the following steps)" - PICS: MCORE.UI.FACTORYRESET verification: | - On both DUT and TH side, on Raspi we do factory reset with the below command. The DUT for cert should follow vendor specific procedure for factory reset + On Raspi factory reset with the below command. sudo rm -rf /tmp/chip_* disabled: true diff --git a/src/app/zap-templates/zcl/data-model/all.xml b/src/app/zap-templates/zcl/data-model/all.xml index 23709faca1ace5..61d39b3b0173ea 100644 --- a/src/app/zap-templates/zcl/data-model/all.xml +++ b/src/app/zap-templates/zcl/data-model/all.xml @@ -18,6 +18,7 @@ + @@ -108,6 +109,7 @@ + diff --git a/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml new file mode 100644 index 00000000000000..7228b8f47a20ab --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + General + Commissioner Control + 0x0751 + COMMISSIONER_CONTROL_CLUSTER + true + true + Supports the ability for clients to request the commissioning of themselves or other nodes onto a fabric which the cluster server can commission onto. + + + + + SupportedDeviceCategories + + + + + This command is sent by a client to request approval for a future CommissionNode call. + + + + + + + + + This command is sent by a client to request that the server begins commissioning a previously approved request. + + + + + + + + + + When received within the timeout specified by CommissionNode, the client SHALL open a commissioning window on to the node which the client called RequestCommissioningApproval to have commissioned. + + + + + + + + + This event SHALL be sent by the server following a RequestCommissioningApproval command which the server responded to with SUCCESS. + + + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml index 5c22b8e93be8da..94774774d53a10 100644 --- a/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml @@ -13,7 +13,6 @@ limitations under the License. --> - @@ -32,6 +31,7 @@ limitations under the License. + @@ -75,7 +75,7 @@ limitations under the License. - + @@ -94,11 +94,13 @@ limitations under the License. true true Electric Vehicle Supply Equipment (EVSE) is equipment used to charge an Electric Vehicle (EV) or Plug-In Hybrid Electric Vehicle. This cluster provides an interface to the functionality of Electric Vehicle Supply Equipment (EVSE) management. - - + - + + + + @@ -113,22 +115,18 @@ limitations under the License. - - - State - SupplyState - FaultState - ChargingEnabledUntil + State + SupplyState + FaultState + ChargingEnabledUntil - - DischargingEnabledUntil - CircuitCapacity - MinimumChargeCurrent - MaximumChargeCurrent + DischargingEnabledUntil + CircuitCapacity + MinimumChargeCurrent + MaximumChargeCurrent - - MaximumDischargeCurrent + MaximumDischargeCurrent UserMaximumChargeCurrent @@ -138,77 +136,75 @@ limitations under the License. RandomizationDelayWindow - - - - NextChargeStartTime + NextChargeStartTime - - NextChargeTargetTime + NextChargeTargetTime - - NextChargeRequiredEnergy + NextChargeRequiredEnergy - - NextChargeTargetSoC + NextChargeTargetSoC - - + ApproximateEVEfficiency - - StateOfCharge + StateOfCharge - - BatteryCapacity + BatteryCapacity - - VehicleID - SessionID - SessionDuration - SessionEnergyCharged + VehicleID + SessionID + SessionDuration + SessionEnergyCharged - - SessionEnergyDischarged + SessionEnergyDischarged Allows a client to disable the EVSE from charging and discharging. + - - - - Allows a client to enable the EVSE to charge an EV. + + + + This command allows a client to enable the EVSE to charge an EV, + - - - Allows a client to enable the EVSE to discharge an EV. + + + Upon receipt, this SHALL allow a client to enable the discharge of an EV, + Allows a client to put the EVSE into a self-diagnostics mode. + - + Allows a client to set the user specified charging targets. + - Allows a client to retrieve the user specified charging targets. + Allows a client to retrieve the current set of charging targets. + Allows a client to clear all stored charging targets. - - + + + The GetTargetsResponse is sent in response to the GetTargets Command. + EVConnected + EVNotDetected @@ -217,19 +213,24 @@ limitations under the License. + EnergyTransferStarted - + + + EnergyTransferStopped + + Fault @@ -237,10 +238,11 @@ limitations under the License. + RFID - + diff --git a/src/app/zap-templates/zcl/data-model/chip/laundry-dryer-controls-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/laundry-dryer-controls-cluster.xml index 11837b8be0e8f4..f126d8836f720c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/laundry-dryer-controls-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/laundry-dryer-controls-cluster.xml @@ -33,8 +33,8 @@ limitations under the License. LAUNDRY_DRYER_CONTROLS_CLUSTER true true - This cluster supports remotely monitoring and controling the different typs of - functionality available to a drying device, such as a laundry dryer. + This cluster provides a way to access options associated with the operation of + a laundry dryer device type. diff --git a/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml index 2c1cd01d67c7b2..b6ee4385fb73ff 100644 --- a/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml @@ -22,7 +22,7 @@ limitations under the License. - + HRAP Thread Border Router Management 0x0452 @@ -33,40 +33,39 @@ limitations under the License. - BorderRouterName + BorderRouterName - BorderAgentID + BorderAgentID - ThreadVersion + ThreadVersion - InterfaceEnabled + InterfaceEnabled - ActiveDatasetTimestamp + ActiveDatasetTimestamp - - + Command to request the active operational dataset of the Thread network to which the border router is connected. This command must be sent over a valid CASE session - + Command to request the pending dataset of the Thread network to which the border router is connected. This command must be sent over a valid CASE session - + Generated response to GetActiveDatasetRequest or GetPendingDatasetRequest commands. - + Command to set or update the active Dataset of the Thread network to which the Border Router is connected. - + Command set or update the pending Dataset of the Thread network to which the Border Router is connected. diff --git a/src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml new file mode 100644 index 00000000000000..0c5a9a1efea2fa --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Energy Management + Water Heater Management + 0x0094 + WATER_HEATER_MANAGEMENT_CLUSTER + This cluster is used to allow clients to control the operation of a hot water heating appliance so that it can be used with energy management. + true + + + + + + + + + true + + HeaterTypes + HeatDemand + TankVolume + EstimatedHeatRequired + TankPercentage + BoostState + + Allows a client to request that the water heater is put into a Boost state. + + + + + + + + + + + Allows a client to cancel an ongoing Boost operation. + + + + + diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json index 95fa00cb7952c7..c6b39c837a1e00 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -33,6 +33,7 @@ "channel-cluster.xml", "clusters-extensions.xml", "color-control-cluster.xml", + "commissioner-control-cluster.xml", "concentration-measurement-cluster.xml", "content-launch-cluster.xml", "content-app-observer-cluster.xml", @@ -129,6 +130,7 @@ "valve-configuration-and-control-cluster.xml", "wake-on-lan-cluster.xml", "washer-controls-cluster.xml", + "water-heater-management-cluster.xml", "wifi-network-diagnostics-cluster.xml", "wifi-network-management-cluster.xml", "window-covering.xml", diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index e3ec959ff64e83..18afa7eacc2f8a 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -32,6 +32,7 @@ "channel-cluster.xml", "clusters-extensions.xml", "color-control-cluster.xml", + "commissioner-control-cluster.xml", "concentration-measurement-cluster.xml", "content-launch-cluster.xml", "content-app-observer-cluster.xml", @@ -127,6 +128,7 @@ "valve-configuration-and-control-cluster.xml", "wake-on-lan-cluster.xml", "washer-controls-cluster.xml", + "water-heater-management-cluster.xml", "wifi-network-diagnostics-cluster.xml", "wifi-network-management-cluster.xml", "window-covering.xml", diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index 4c7757224b1a7d..dc324968991adc 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -23,6 +23,7 @@ "CHANNEL_CLUSTER": [], "CLIENT_MONITORING_CLUSTER": [], "COLOR_CONTROL_CLUSTER": [], + "COMMISSIONER_CONTROL_CLUSTER": [], "COMMISSIONING_CLUSTER": [], "CONTENT_LAUNCHER_CLUSTER": [], "CONTENT_CONTROL_CLUSTER": [], @@ -168,6 +169,7 @@ ], "CHANNEL_CLUSTER": ["channel-server"], "COLOR_CONTROL_CLUSTER": ["color-control-server"], + "COMMISSIONER_CONTROL_CLUSTER": ["commissioner-control-server"], "COMMISSIONING_CLUSTER": [], "CONTENT_LAUNCHER_CLUSTER": ["content-launch-server"], "CONTENT_CONTROL_CLUSTER": ["content-control-server"], diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 444b48bcf12b49..5212350c913696 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1844,13 +1844,25 @@ void DeviceCommissioner::CleanupCommissioning(DeviceProxy * proxy, NodeId nodeId if (completionStatus.err == CHIP_NO_ERROR) { + // CommissioningStageComplete uses mDeviceBeingCommissioned, which can + // be commissionee if we are cleaning up before we've gone operational. Normally + // that would not happen in this non-error case, _except_ if we were told to skip sending + // CommissioningComplete: in that case we do not have an operational DeviceProxy, so + // we're using our CommissioneeDeviceProxy to do a successful cleanup. + // + // This means we have to call CommissioningStageComplete() before we destroy commissionee. + // + // This should be safe, because CommissioningStageComplete() does not call CleanupCommissioning + // when called in the cleanup stage (which is where we are), and StopPairing does not directly release + // mDeviceBeingCommissioned. + CommissioningStageComplete(CHIP_NO_ERROR); + CommissioneeDeviceProxy * commissionee = FindCommissioneeDevice(nodeId); if (commissionee != nullptr) { ReleaseCommissioneeDevice(commissionee); } // Send the callbacks, we're done. - CommissioningStageComplete(CHIP_NO_ERROR); SendCommissioningCompleteCallbacks(nodeId, mCommissioningCompletionStatus); } else if (completionStatus.err == CHIP_ERROR_CANCELLED) @@ -1929,12 +1941,13 @@ void DeviceCommissioner::CleanupDoneAfterError() VerifyOrReturn(mDeviceBeingCommissioned != nullptr); NodeId nodeId = mDeviceBeingCommissioned->GetDeviceId(); - // At this point, we also want to close off the pase session so we need to re-establish - CommissioneeDeviceProxy * commissionee = FindCommissioneeDevice(nodeId); // Signal completion - this will reset mDeviceBeingCommissioned. CommissioningStageComplete(CHIP_NO_ERROR); + // At this point, we also want to close off the pase session so we need to re-establish + CommissioneeDeviceProxy * commissionee = FindCommissioneeDevice(nodeId); + // If we've disarmed the failsafe, it's because we're starting again, so kill the pase connection. if (commissionee != nullptr) { diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index 0add2f8c6c5095..8459f1887c746b 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -2933,8 +2933,8 @@ cluster OvenMode = 73 { command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } -/** This cluster supports remotely monitoring and controling the different typs of - functionality available to a drying device, such as a laundry dryer. */ +/** This cluster provides a way to access options associated with the operation of + a laundry dryer device type. */ cluster LaundryDryerControls = 74 { revision 1; @@ -4318,6 +4318,64 @@ cluster ElectricalEnergyMeasurement = 145 { readonly attribute int16u clusterRevision = 65533; } +/** This cluster is used to allow clients to control the operation of a hot water heating appliance so that it can be used with energy management. */ +provisional cluster WaterHeaterManagement = 148 { + revision 1; + + enum BoostStateEnum : enum8 { + kInactive = 0; + kActive = 1; + } + + bitmap Feature : bitmap32 { + kEnergyManagement = 0x1; + kTankPercent = 0x2; + } + + bitmap WaterHeaterDemandBitmap : bitmap8 { + kImmersionElement1 = 0x1; + kImmersionElement2 = 0x2; + kHeatPump = 0x4; + kBoiler = 0x8; + kOther = 0x10; + } + + bitmap WaterHeaterTypeBitmap : bitmap8 { + kImmersionElement1 = 0x1; + kImmersionElement2 = 0x2; + kHeatPump = 0x4; + kBoiler = 0x8; + kOther = 0x10; + } + + readonly attribute WaterHeaterTypeBitmap heaterTypes = 0; + readonly attribute WaterHeaterDemandBitmap heatDemand = 1; + readonly attribute optional int16u tankVolume = 2; + readonly attribute optional energy_mwh estimatedHeatRequired = 3; + readonly attribute optional percent tankPercentage = 4; + readonly attribute BoostStateEnum boostState = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct BoostRequest { + elapsed_s duration = 0; + optional boolean oneShot = 1; + optional boolean emergencyBoost = 2; + optional temperature temporarySetpoint = 3; + optional percent targetPercentage = 4; + optional percent targetReheat = 5; + } + + /** Allows a client to request that the water heater is put into a Boost state. */ + command access(invoke: manage) Boost(BoostRequest): DefaultSuccess = 0; + /** Allows a client to cancel an ongoing Boost operation. */ + command access(invoke: manage) CancelBoost(): DefaultSuccess = 1; +} + /** This cluster provides an interface to the functionality of Smart Energy Demand Response and Load Control. */ provisional cluster DemandResponseLoadControl = 150 { revision 4; @@ -4830,7 +4888,7 @@ provisional cluster DeviceEnergyManagement = 152 { /** Electric Vehicle Supply Equipment (EVSE) is equipment used to charge an Electric Vehicle (EV) or Plug-In Hybrid Electric Vehicle. This cluster provides an interface to the functionality of Electric Vehicle Supply Equipment (EVSE) management. */ cluster EnergyEvse = 153 { - revision 2; + revision 4; enum EnergyTransferStoppedReasonEnum : enum8 { kEVStopped = 0; @@ -4874,6 +4932,7 @@ cluster EnergyEvse = 153 { kDischargingEnabled = 2; kDisabledError = 3; kDisabledDiagnostics = 4; + kEnabled = 5; } bitmap Feature : bitmap32 { @@ -4921,6 +4980,7 @@ cluster EnergyEvse = 153 { int32u sessionID = 0; StateEnum state = 1; amperage_ma maximumCurrent = 2; + optional amperage_ma maximumDischargeCurrent = 3; } info event EnergyTransferStopped = 3 { @@ -4928,6 +4988,7 @@ cluster EnergyEvse = 153 { StateEnum state = 1; EnergyTransferStoppedReasonEnum reason = 2; energy_mwh energyTransferred = 4; + optional energy_mwh energyDischarged = 5; } critical event Fault = 4 { @@ -4992,15 +5053,15 @@ cluster EnergyEvse = 153 { /** Allows a client to disable the EVSE from charging and discharging. */ timed command Disable(): DefaultSuccess = 1; - /** Allows a client to enable the EVSE to charge an EV. */ + /** This command allows a client to enable the EVSE to charge an EV, */ timed command EnableCharging(EnableChargingRequest): DefaultSuccess = 2; - /** Allows a client to enable the EVSE to discharge an EV. */ + /** Upon receipt, this SHALL allow a client to enable the discharge of an EV, */ timed command EnableDischarging(EnableDischargingRequest): DefaultSuccess = 3; /** Allows a client to put the EVSE into a self-diagnostics mode. */ timed command StartDiagnostics(): DefaultSuccess = 4; /** Allows a client to set the user specified charging targets. */ timed command SetTargets(SetTargetsRequest): DefaultSuccess = 5; - /** Allows a client to retrieve the user specified charging targets. */ + /** Allows a client to retrieve the current set of charging targets. */ timed command GetTargets(): GetTargetsResponse = 6; /** Allows a client to clear all stored charging targets. */ timed command ClearTargets(): DefaultSuccess = 7; @@ -8010,18 +8071,18 @@ cluster WiFiNetworkManagement = 1105 { } /** Manage the Thread network of Thread Border Router */ -cluster ThreadBorderRouterManagement = 1106 { +provisional cluster ThreadBorderRouterManagement = 1106 { revision 1; bitmap Feature : bitmap32 { kPANChange = 0x1; } - readonly attribute char_string<63> borderRouterName = 0; - readonly attribute octet_string<254> borderAgentID = 1; - readonly attribute int16u threadVersion = 2; - readonly attribute boolean interfaceEnabled = 3; - readonly attribute nullable int64u activeDatasetTimestamp = 5; + provisional readonly attribute char_string<63> borderRouterName = 0; + provisional readonly attribute octet_string<254> borderAgentID = 1; + provisional readonly attribute int16u threadVersion = 2; + provisional readonly attribute boolean interfaceEnabled = 3; + provisional readonly attribute nullable int64u activeDatasetTimestamp = 4; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -8029,7 +8090,7 @@ cluster ThreadBorderRouterManagement = 1106 { readonly attribute bitmap32 featureMap = 65532; readonly attribute int16u clusterRevision = 65533; - response struct DatasetResponse = 3 { + response struct DatasetResponse = 2 { octet_string<254> dataset = 0; } @@ -8047,9 +8108,9 @@ cluster ThreadBorderRouterManagement = 1106 { /** Command to request the pending dataset of the Thread network to which the border router is connected. This command must be sent over a valid CASE session */ command access(invoke: manage) GetPendingDatasetRequest(): DatasetResponse = 1; /** Command to set or update the active Dataset of the Thread network to which the Border Router is connected. */ - command access(invoke: manage) SetActiveDatasetRequest(SetActiveDatasetRequestRequest): DefaultSuccess = 4; + command access(invoke: manage) SetActiveDatasetRequest(SetActiveDatasetRequestRequest): DefaultSuccess = 3; /** Command set or update the pending Dataset of the Thread network to which the Border Router is connected. */ - command access(invoke: manage) SetPendingDatasetRequest(SetPendingDatasetRequestRequest): DefaultSuccess = 5; + command access(invoke: manage) SetPendingDatasetRequest(SetPendingDatasetRequestRequest): DefaultSuccess = 4; } /** Manages the names and credentials of Thread networks visible to the user. */ @@ -9134,6 +9195,57 @@ provisional cluster ContentAppObserver = 1296 { command ContentAppMessage(ContentAppMessageRequest): ContentAppMessageResponse = 0; } +/** Supports the ability for clients to request the commissioning of themselves or other nodes onto a fabric which the cluster server can commission onto. */ +provisional cluster CommissionerControl = 1873 { + revision 1; + + bitmap SupportedDeviceCategoryBitmap : bitmap32 { + kFabricSynchronization = 0x1; + } + + fabric_sensitive info event access(read: manage) CommissioningRequestResult = 0 { + int64u requestId = 0; + node_id clientNodeId = 1; + enum8 statusCode = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute access(read: manage) SupportedDeviceCategoryBitmap supportedDeviceCategories = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct RequestCommissioningApprovalRequest { + int64u requestId = 0; + vendor_id vendorId = 1; + int16u productId = 2; + optional char_string<64> label = 3; + } + + request struct CommissionNodeRequest { + int64u requestId = 0; + int16u responseTimeoutSeconds = 1; + optional octet_string ipAddress = 2; + optional int16u port = 3; + } + + response struct ReverseOpenCommissioningWindow = 2 { + int16u commissioningTimeout = 0; + octet_string PAKEPasscodeVerifier = 1; + int16u discriminator = 2; + int32u iterations = 3; + octet_string<32> salt = 4; + } + + /** This command is sent by a client to request approval for a future CommissionNode call. */ + command access(invoke: manage) RequestCommissioningApproval(RequestCommissioningApprovalRequest): DefaultSuccess = 0; + /** This command is sent by a client to request that the server begins commissioning a previously approved request. */ + command access(invoke: manage) CommissionNode(CommissionNodeRequest): ReverseOpenCommissioningWindow = 1; +} + /** Attributes related to the electrical properties of a device. This cluster is used by power outlets and other devices that need to provide instantaneous data as opposed to metrology data which should be retrieved from the metering cluster.. */ deprecated cluster ElectricalMeasurement = 2820 { revision 3; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index e96b2925e77a65..0e027a3c0c0647 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -30208,17 +30208,15 @@ public void onSuccess(byte[] tlv) { } } - public static class DemandResponseLoadControlCluster extends BaseChipCluster { - public static final long CLUSTER_ID = 150L; - - private static final long LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID = 0L; - private static final long NUMBER_OF_LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID = 1L; - private static final long EVENTS_ATTRIBUTE_ID = 2L; - private static final long ACTIVE_EVENTS_ATTRIBUTE_ID = 3L; - private static final long NUMBER_OF_EVENTS_PER_PROGRAM_ATTRIBUTE_ID = 4L; - private static final long NUMBER_OF_TRANSITIONS_ATTRIBUTE_ID = 5L; - private static final long DEFAULT_RANDOM_START_ATTRIBUTE_ID = 6L; - private static final long DEFAULT_RANDOM_DURATION_ATTRIBUTE_ID = 7L; + public static class WaterHeaterManagementCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 148L; + + private static final long HEATER_TYPES_ATTRIBUTE_ID = 0L; + private static final long HEAT_DEMAND_ATTRIBUTE_ID = 1L; + private static final long TANK_VOLUME_ATTRIBUTE_ID = 2L; + private static final long ESTIMATED_HEAT_REQUIRED_ATTRIBUTE_ID = 3L; + private static final long TANK_PERCENTAGE_ATTRIBUTE_ID = 4L; + private static final long BOOST_STATE_ATTRIBUTE_ID = 5L; private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; @@ -30226,7 +30224,7 @@ public static class DemandResponseLoadControlCluster extends BaseChipCluster { private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L; private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L; - public DemandResponseLoadControlCluster(long devicePtr, int endpointId) { + public WaterHeaterManagementCluster(long devicePtr, int endpointId) { super(devicePtr, endpointId, CLUSTER_ID); } @@ -30236,81 +30234,37 @@ public long initWithDevice(long devicePtr, int endpointId) { return 0L; } - public void registerLoadControlProgramRequest(DefaultClusterCallback callback, ChipStructs.DemandResponseLoadControlClusterLoadControlProgramStruct loadControlProgram) { - registerLoadControlProgramRequest(callback, loadControlProgram, 0); + public void boost(DefaultClusterCallback callback, Long duration, Optional oneShot, Optional emergencyBoost, Optional temporarySetpoint, Optional targetPercentage, Optional targetReheat) { + boost(callback, duration, oneShot, emergencyBoost, temporarySetpoint, targetPercentage, targetReheat, 0); } - public void registerLoadControlProgramRequest(DefaultClusterCallback callback, ChipStructs.DemandResponseLoadControlClusterLoadControlProgramStruct loadControlProgram, int timedInvokeTimeoutMs) { + public void boost(DefaultClusterCallback callback, Long duration, Optional oneShot, Optional emergencyBoost, Optional temporarySetpoint, Optional targetPercentage, Optional targetReheat, int timedInvokeTimeoutMs) { final long commandId = 0L; ArrayList elements = new ArrayList<>(); - final long loadControlProgramFieldID = 0L; - BaseTLVType loadControlProgramtlvValue = loadControlProgram.encodeTlv(); - elements.add(new StructElement(loadControlProgramFieldID, loadControlProgramtlvValue)); - - StructType commandArgs = new StructType(elements); - invoke(new InvokeCallbackImpl(callback) { - @Override - public void onResponse(StructType invokeStructValue) { - callback.onSuccess(); - }}, commandId, commandArgs, timedInvokeTimeoutMs); - } - - public void unregisterLoadControlProgramRequest(DefaultClusterCallback callback, byte[] loadControlProgramID) { - unregisterLoadControlProgramRequest(callback, loadControlProgramID, 0); - } - - public void unregisterLoadControlProgramRequest(DefaultClusterCallback callback, byte[] loadControlProgramID, int timedInvokeTimeoutMs) { - final long commandId = 1L; - - ArrayList elements = new ArrayList<>(); - final long loadControlProgramIDFieldID = 0L; - BaseTLVType loadControlProgramIDtlvValue = new ByteArrayType(loadControlProgramID); - elements.add(new StructElement(loadControlProgramIDFieldID, loadControlProgramIDtlvValue)); - - StructType commandArgs = new StructType(elements); - invoke(new InvokeCallbackImpl(callback) { - @Override - public void onResponse(StructType invokeStructValue) { - callback.onSuccess(); - }}, commandId, commandArgs, timedInvokeTimeoutMs); - } - - public void addLoadControlEventRequest(DefaultClusterCallback callback, ChipStructs.DemandResponseLoadControlClusterLoadControlEventStruct event) { - addLoadControlEventRequest(callback, event, 0); - } - - public void addLoadControlEventRequest(DefaultClusterCallback callback, ChipStructs.DemandResponseLoadControlClusterLoadControlEventStruct event, int timedInvokeTimeoutMs) { - final long commandId = 2L; - - ArrayList elements = new ArrayList<>(); - final long eventFieldID = 0L; - BaseTLVType eventtlvValue = event.encodeTlv(); - elements.add(new StructElement(eventFieldID, eventtlvValue)); + final long durationFieldID = 0L; + BaseTLVType durationtlvValue = new UIntType(duration); + elements.add(new StructElement(durationFieldID, durationtlvValue)); - StructType commandArgs = new StructType(elements); - invoke(new InvokeCallbackImpl(callback) { - @Override - public void onResponse(StructType invokeStructValue) { - callback.onSuccess(); - }}, commandId, commandArgs, timedInvokeTimeoutMs); - } + final long oneShotFieldID = 1L; + BaseTLVType oneShottlvValue = oneShot.map((nonOptionaloneShot) -> new BooleanType(nonOptionaloneShot)).orElse(new EmptyType()); + elements.add(new StructElement(oneShotFieldID, oneShottlvValue)); - public void removeLoadControlEventRequest(DefaultClusterCallback callback, byte[] eventID, Integer cancelControl) { - removeLoadControlEventRequest(callback, eventID, cancelControl, 0); - } + final long emergencyBoostFieldID = 2L; + BaseTLVType emergencyBoosttlvValue = emergencyBoost.map((nonOptionalemergencyBoost) -> new BooleanType(nonOptionalemergencyBoost)).orElse(new EmptyType()); + elements.add(new StructElement(emergencyBoostFieldID, emergencyBoosttlvValue)); - public void removeLoadControlEventRequest(DefaultClusterCallback callback, byte[] eventID, Integer cancelControl, int timedInvokeTimeoutMs) { - final long commandId = 3L; + final long temporarySetpointFieldID = 3L; + BaseTLVType temporarySetpointtlvValue = temporarySetpoint.map((nonOptionaltemporarySetpoint) -> new IntType(nonOptionaltemporarySetpoint)).orElse(new EmptyType()); + elements.add(new StructElement(temporarySetpointFieldID, temporarySetpointtlvValue)); - ArrayList elements = new ArrayList<>(); - final long eventIDFieldID = 0L; - BaseTLVType eventIDtlvValue = new ByteArrayType(eventID); - elements.add(new StructElement(eventIDFieldID, eventIDtlvValue)); + final long targetPercentageFieldID = 4L; + BaseTLVType targetPercentagetlvValue = targetPercentage.map((nonOptionaltargetPercentage) -> new UIntType(nonOptionaltargetPercentage)).orElse(new EmptyType()); + elements.add(new StructElement(targetPercentageFieldID, targetPercentagetlvValue)); - final long cancelControlFieldID = 1L; - BaseTLVType cancelControltlvValue = new UIntType(cancelControl); - elements.add(new StructElement(cancelControlFieldID, cancelControltlvValue)); + final long targetReheatFieldID = 5L; + BaseTLVType targetReheattlvValue = targetReheat.map((nonOptionaltargetReheat) -> new UIntType(nonOptionaltargetReheat)).orElse(new EmptyType()); + elements.add(new StructElement(targetReheatFieldID, targetReheattlvValue)); StructType commandArgs = new StructType(elements); invoke(new InvokeCallbackImpl(callback) { @@ -30320,12 +30274,12 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, commandArgs, timedInvokeTimeoutMs); } - public void clearLoadControlEventsRequest(DefaultClusterCallback callback) { - clearLoadControlEventsRequest(callback, 0); + public void cancelBoost(DefaultClusterCallback callback) { + cancelBoost(callback, 0); } - public void clearLoadControlEventsRequest(DefaultClusterCallback callback, int timedInvokeTimeoutMs) { - final long commandId = 4L; + public void cancelBoost(DefaultClusterCallback callback, int timedInvokeTimeoutMs) { + final long commandId = 1L; ArrayList elements = new ArrayList<>(); StructType commandArgs = new StructType(elements); @@ -30336,18 +30290,6 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, commandArgs, timedInvokeTimeoutMs); } - public interface LoadControlProgramsAttributeCallback extends BaseAttributeCallback { - void onSuccess(List value); - } - - public interface EventsAttributeCallback extends BaseAttributeCallback { - void onSuccess(List value); - } - - public interface ActiveEventsAttributeCallback extends BaseAttributeCallback { - void onSuccess(List value); - } - public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } @@ -30364,35 +30306,9 @@ public interface AttributeListAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } - public void readLoadControlProgramsAttribute( - LoadControlProgramsAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID); - - readAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID, true); - } - - public void subscribeLoadControlProgramsAttribute( - LoadControlProgramsAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID); - - subscribeAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID, minInterval, maxInterval); - } - - public void readNumberOfLoadControlProgramsAttribute( + public void readHeaterTypesAttribute( IntegerAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NUMBER_OF_LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID); + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, HEATER_TYPES_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -30400,12 +30316,12 @@ public void onSuccess(byte[] tlv) { Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, NUMBER_OF_LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID, true); + }, HEATER_TYPES_ATTRIBUTE_ID, true); } - public void subscribeNumberOfLoadControlProgramsAttribute( + public void subscribeHeaterTypesAttribute( IntegerAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NUMBER_OF_LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID); + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, HEATER_TYPES_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -30413,64 +30329,38 @@ public void onSuccess(byte[] tlv) { Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, NUMBER_OF_LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID, minInterval, maxInterval); - } - - public void readEventsAttribute( - EventsAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENTS_ATTRIBUTE_ID); - - readAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, EVENTS_ATTRIBUTE_ID, true); - } - - public void subscribeEventsAttribute( - EventsAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENTS_ATTRIBUTE_ID); - - subscribeAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, EVENTS_ATTRIBUTE_ID, minInterval, maxInterval); + }, HEATER_TYPES_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readActiveEventsAttribute( - ActiveEventsAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACTIVE_EVENTS_ATTRIBUTE_ID); + public void readHeatDemandAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, HEAT_DEMAND_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, ACTIVE_EVENTS_ATTRIBUTE_ID, true); + }, HEAT_DEMAND_ATTRIBUTE_ID, true); } - public void subscribeActiveEventsAttribute( - ActiveEventsAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACTIVE_EVENTS_ATTRIBUTE_ID); + public void subscribeHeatDemandAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, HEAT_DEMAND_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, ACTIVE_EVENTS_ATTRIBUTE_ID, minInterval, maxInterval); + }, HEAT_DEMAND_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readNumberOfEventsPerProgramAttribute( + public void readTankVolumeAttribute( IntegerAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NUMBER_OF_EVENTS_PER_PROGRAM_ATTRIBUTE_ID); + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, TANK_VOLUME_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -30478,12 +30368,12 @@ public void onSuccess(byte[] tlv) { Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, NUMBER_OF_EVENTS_PER_PROGRAM_ATTRIBUTE_ID, true); + }, TANK_VOLUME_ATTRIBUTE_ID, true); } - public void subscribeNumberOfEventsPerProgramAttribute( + public void subscribeTankVolumeAttribute( IntegerAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NUMBER_OF_EVENTS_PER_PROGRAM_ATTRIBUTE_ID); + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, TANK_VOLUME_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -30491,38 +30381,38 @@ public void onSuccess(byte[] tlv) { Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, NUMBER_OF_EVENTS_PER_PROGRAM_ATTRIBUTE_ID, minInterval, maxInterval); + }, TANK_VOLUME_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readNumberOfTransitionsAttribute( - IntegerAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NUMBER_OF_TRANSITIONS_ATTRIBUTE_ID); + public void readEstimatedHeatRequiredAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ESTIMATED_HEAT_REQUIRED_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, NUMBER_OF_TRANSITIONS_ATTRIBUTE_ID, true); + }, ESTIMATED_HEAT_REQUIRED_ATTRIBUTE_ID, true); } - public void subscribeNumberOfTransitionsAttribute( - IntegerAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NUMBER_OF_TRANSITIONS_ATTRIBUTE_ID); + public void subscribeEstimatedHeatRequiredAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ESTIMATED_HEAT_REQUIRED_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, NUMBER_OF_TRANSITIONS_ATTRIBUTE_ID, minInterval, maxInterval); + }, ESTIMATED_HEAT_REQUIRED_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readDefaultRandomStartAttribute( + public void readTankPercentageAttribute( IntegerAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, DEFAULT_RANDOM_START_ATTRIBUTE_ID); + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, TANK_PERCENTAGE_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -30530,21 +30420,12 @@ public void onSuccess(byte[] tlv) { Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, DEFAULT_RANDOM_START_ATTRIBUTE_ID, true); + }, TANK_PERCENTAGE_ATTRIBUTE_ID, true); } - public void writeDefaultRandomStartAttribute(DefaultClusterCallback callback, Integer value) { - writeDefaultRandomStartAttribute(callback, value, 0); - } - - public void writeDefaultRandomStartAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { - BaseTLVType tlvValue = new UIntType(value); - writeAttribute(new WriteAttributesCallbackImpl(callback), DEFAULT_RANDOM_START_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); - } - - public void subscribeDefaultRandomStartAttribute( + public void subscribeTankPercentageAttribute( IntegerAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, DEFAULT_RANDOM_START_ATTRIBUTE_ID); + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, TANK_PERCENTAGE_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -30552,12 +30433,12 @@ public void onSuccess(byte[] tlv) { Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, DEFAULT_RANDOM_START_ATTRIBUTE_ID, minInterval, maxInterval); + }, TANK_PERCENTAGE_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readDefaultRandomDurationAttribute( + public void readBoostStateAttribute( IntegerAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, DEFAULT_RANDOM_DURATION_ATTRIBUTE_ID); + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, BOOST_STATE_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -30565,21 +30446,12 @@ public void onSuccess(byte[] tlv) { Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, DEFAULT_RANDOM_DURATION_ATTRIBUTE_ID, true); - } - - public void writeDefaultRandomDurationAttribute(DefaultClusterCallback callback, Integer value) { - writeDefaultRandomDurationAttribute(callback, value, 0); - } - - public void writeDefaultRandomDurationAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { - BaseTLVType tlvValue = new UIntType(value); - writeAttribute(new WriteAttributesCallbackImpl(callback), DEFAULT_RANDOM_DURATION_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + }, BOOST_STATE_ATTRIBUTE_ID, true); } - public void subscribeDefaultRandomDurationAttribute( + public void subscribeBoostStateAttribute( IntegerAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, DEFAULT_RANDOM_DURATION_ATTRIBUTE_ID); + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, BOOST_STATE_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -30587,7 +30459,7 @@ public void onSuccess(byte[] tlv) { Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, DEFAULT_RANDOM_DURATION_ATTRIBUTE_ID, minInterval, maxInterval); + }, BOOST_STATE_ATTRIBUTE_ID, minInterval, maxInterval); } public void readGeneratedCommandListAttribute( @@ -30747,11 +30619,17 @@ public void onSuccess(byte[] tlv) { } } - public static class MessagesCluster extends BaseChipCluster { - public static final long CLUSTER_ID = 151L; + public static class DemandResponseLoadControlCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 150L; - private static final long MESSAGES_ATTRIBUTE_ID = 0L; - private static final long ACTIVE_MESSAGE_I_DS_ATTRIBUTE_ID = 1L; + private static final long LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID = 0L; + private static final long NUMBER_OF_LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID = 1L; + private static final long EVENTS_ATTRIBUTE_ID = 2L; + private static final long ACTIVE_EVENTS_ATTRIBUTE_ID = 3L; + private static final long NUMBER_OF_EVENTS_PER_PROGRAM_ATTRIBUTE_ID = 4L; + private static final long NUMBER_OF_TRANSITIONS_ATTRIBUTE_ID = 5L; + private static final long DEFAULT_RANDOM_START_ATTRIBUTE_ID = 6L; + private static final long DEFAULT_RANDOM_DURATION_ATTRIBUTE_ID = 7L; private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; @@ -30759,7 +30637,7 @@ public static class MessagesCluster extends BaseChipCluster { private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L; private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L; - public MessagesCluster(long devicePtr, int endpointId) { + public DemandResponseLoadControlCluster(long devicePtr, int endpointId) { super(devicePtr, endpointId, CLUSTER_ID); } @@ -30769,27 +30647,560 @@ public long initWithDevice(long devicePtr, int endpointId) { return 0L; } - public void presentMessagesRequest(DefaultClusterCallback callback, byte[] messageID, Integer priority, Integer messageControl, @Nullable Long startTime, @Nullable Long duration, String messageText, Optional> responses) { - presentMessagesRequest(callback, messageID, priority, messageControl, startTime, duration, messageText, responses, 0); + public void registerLoadControlProgramRequest(DefaultClusterCallback callback, ChipStructs.DemandResponseLoadControlClusterLoadControlProgramStruct loadControlProgram) { + registerLoadControlProgramRequest(callback, loadControlProgram, 0); } - public void presentMessagesRequest(DefaultClusterCallback callback, byte[] messageID, Integer priority, Integer messageControl, @Nullable Long startTime, @Nullable Long duration, String messageText, Optional> responses, int timedInvokeTimeoutMs) { + public void registerLoadControlProgramRequest(DefaultClusterCallback callback, ChipStructs.DemandResponseLoadControlClusterLoadControlProgramStruct loadControlProgram, int timedInvokeTimeoutMs) { final long commandId = 0L; ArrayList elements = new ArrayList<>(); - final long messageIDFieldID = 0L; - BaseTLVType messageIDtlvValue = new ByteArrayType(messageID); - elements.add(new StructElement(messageIDFieldID, messageIDtlvValue)); - - final long priorityFieldID = 1L; - BaseTLVType prioritytlvValue = new UIntType(priority); - elements.add(new StructElement(priorityFieldID, prioritytlvValue)); - - final long messageControlFieldID = 2L; - BaseTLVType messageControltlvValue = new UIntType(messageControl); - elements.add(new StructElement(messageControlFieldID, messageControltlvValue)); + final long loadControlProgramFieldID = 0L; + BaseTLVType loadControlProgramtlvValue = loadControlProgram.encodeTlv(); + elements.add(new StructElement(loadControlProgramFieldID, loadControlProgramtlvValue)); - final long startTimeFieldID = 3L; + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public void unregisterLoadControlProgramRequest(DefaultClusterCallback callback, byte[] loadControlProgramID) { + unregisterLoadControlProgramRequest(callback, loadControlProgramID, 0); + } + + public void unregisterLoadControlProgramRequest(DefaultClusterCallback callback, byte[] loadControlProgramID, int timedInvokeTimeoutMs) { + final long commandId = 1L; + + ArrayList elements = new ArrayList<>(); + final long loadControlProgramIDFieldID = 0L; + BaseTLVType loadControlProgramIDtlvValue = new ByteArrayType(loadControlProgramID); + elements.add(new StructElement(loadControlProgramIDFieldID, loadControlProgramIDtlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public void addLoadControlEventRequest(DefaultClusterCallback callback, ChipStructs.DemandResponseLoadControlClusterLoadControlEventStruct event) { + addLoadControlEventRequest(callback, event, 0); + } + + public void addLoadControlEventRequest(DefaultClusterCallback callback, ChipStructs.DemandResponseLoadControlClusterLoadControlEventStruct event, int timedInvokeTimeoutMs) { + final long commandId = 2L; + + ArrayList elements = new ArrayList<>(); + final long eventFieldID = 0L; + BaseTLVType eventtlvValue = event.encodeTlv(); + elements.add(new StructElement(eventFieldID, eventtlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public void removeLoadControlEventRequest(DefaultClusterCallback callback, byte[] eventID, Integer cancelControl) { + removeLoadControlEventRequest(callback, eventID, cancelControl, 0); + } + + public void removeLoadControlEventRequest(DefaultClusterCallback callback, byte[] eventID, Integer cancelControl, int timedInvokeTimeoutMs) { + final long commandId = 3L; + + ArrayList elements = new ArrayList<>(); + final long eventIDFieldID = 0L; + BaseTLVType eventIDtlvValue = new ByteArrayType(eventID); + elements.add(new StructElement(eventIDFieldID, eventIDtlvValue)); + + final long cancelControlFieldID = 1L; + BaseTLVType cancelControltlvValue = new UIntType(cancelControl); + elements.add(new StructElement(cancelControlFieldID, cancelControltlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public void clearLoadControlEventsRequest(DefaultClusterCallback callback) { + clearLoadControlEventsRequest(callback, 0); + } + + public void clearLoadControlEventsRequest(DefaultClusterCallback callback, int timedInvokeTimeoutMs) { + final long commandId = 4L; + + ArrayList elements = new ArrayList<>(); + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public interface LoadControlProgramsAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface EventsAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface ActiveEventsAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AcceptedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface EventListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AttributeListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public void readLoadControlProgramsAttribute( + LoadControlProgramsAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID, true); + } + + public void subscribeLoadControlProgramsAttribute( + LoadControlProgramsAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readNumberOfLoadControlProgramsAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NUMBER_OF_LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, NUMBER_OF_LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID, true); + } + + public void subscribeNumberOfLoadControlProgramsAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NUMBER_OF_LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, NUMBER_OF_LOAD_CONTROL_PROGRAMS_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readEventsAttribute( + EventsAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENTS_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENTS_ATTRIBUTE_ID, true); + } + + public void subscribeEventsAttribute( + EventsAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENTS_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENTS_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readActiveEventsAttribute( + ActiveEventsAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACTIVE_EVENTS_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACTIVE_EVENTS_ATTRIBUTE_ID, true); + } + + public void subscribeActiveEventsAttribute( + ActiveEventsAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACTIVE_EVENTS_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACTIVE_EVENTS_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readNumberOfEventsPerProgramAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NUMBER_OF_EVENTS_PER_PROGRAM_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, NUMBER_OF_EVENTS_PER_PROGRAM_ATTRIBUTE_ID, true); + } + + public void subscribeNumberOfEventsPerProgramAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NUMBER_OF_EVENTS_PER_PROGRAM_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, NUMBER_OF_EVENTS_PER_PROGRAM_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readNumberOfTransitionsAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NUMBER_OF_TRANSITIONS_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, NUMBER_OF_TRANSITIONS_ATTRIBUTE_ID, true); + } + + public void subscribeNumberOfTransitionsAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NUMBER_OF_TRANSITIONS_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, NUMBER_OF_TRANSITIONS_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readDefaultRandomStartAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, DEFAULT_RANDOM_START_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, DEFAULT_RANDOM_START_ATTRIBUTE_ID, true); + } + + public void writeDefaultRandomStartAttribute(DefaultClusterCallback callback, Integer value) { + writeDefaultRandomStartAttribute(callback, value, 0); + } + + public void writeDefaultRandomStartAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = new UIntType(value); + writeAttribute(new WriteAttributesCallbackImpl(callback), DEFAULT_RANDOM_START_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeDefaultRandomStartAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, DEFAULT_RANDOM_START_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, DEFAULT_RANDOM_START_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readDefaultRandomDurationAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, DEFAULT_RANDOM_DURATION_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, DEFAULT_RANDOM_DURATION_ATTRIBUTE_ID, true); + } + + public void writeDefaultRandomDurationAttribute(DefaultClusterCallback callback, Integer value) { + writeDefaultRandomDurationAttribute(callback, value, 0); + } + + public void writeDefaultRandomDurationAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = new UIntType(value); + writeAttribute(new WriteAttributesCallbackImpl(callback), DEFAULT_RANDOM_DURATION_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeDefaultRandomDurationAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, DEFAULT_RANDOM_DURATION_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, DEFAULT_RANDOM_DURATION_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readEventListAttribute( + EventListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeEventListAttribute( + EventListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAttributeListAttribute( + AttributeListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAttributeListAttribute( + AttributeListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readFeatureMapAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, true); + } + + public void subscribeFeatureMapAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readClusterRevisionAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, true); + } + + public void subscribeClusterRevisionAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, minInterval, maxInterval); + } + } + + public static class MessagesCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 151L; + + private static final long MESSAGES_ATTRIBUTE_ID = 0L; + private static final long ACTIVE_MESSAGE_I_DS_ATTRIBUTE_ID = 1L; + private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; + private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; + private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; + private static final long ATTRIBUTE_LIST_ATTRIBUTE_ID = 65531L; + private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L; + private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L; + + public MessagesCluster(long devicePtr, int endpointId) { + super(devicePtr, endpointId, CLUSTER_ID); + } + + @Override + @Deprecated + public long initWithDevice(long devicePtr, int endpointId) { + return 0L; + } + + public void presentMessagesRequest(DefaultClusterCallback callback, byte[] messageID, Integer priority, Integer messageControl, @Nullable Long startTime, @Nullable Long duration, String messageText, Optional> responses) { + presentMessagesRequest(callback, messageID, priority, messageControl, startTime, duration, messageText, responses, 0); + } + + public void presentMessagesRequest(DefaultClusterCallback callback, byte[] messageID, Integer priority, Integer messageControl, @Nullable Long startTime, @Nullable Long duration, String messageText, Optional> responses, int timedInvokeTimeoutMs) { + final long commandId = 0L; + + ArrayList elements = new ArrayList<>(); + final long messageIDFieldID = 0L; + BaseTLVType messageIDtlvValue = new ByteArrayType(messageID); + elements.add(new StructElement(messageIDFieldID, messageIDtlvValue)); + + final long priorityFieldID = 1L; + BaseTLVType prioritytlvValue = new UIntType(priority); + elements.add(new StructElement(priorityFieldID, prioritytlvValue)); + + final long messageControlFieldID = 2L; + BaseTLVType messageControltlvValue = new UIntType(messageControl); + elements.add(new StructElement(messageControlFieldID, messageControltlvValue)); + + final long startTimeFieldID = 3L; BaseTLVType startTimetlvValue = startTime != null ? new UIntType(startTime) : new NullType(); elements.add(new StructElement(startTimeFieldID, startTimetlvValue)); @@ -53618,7 +54029,7 @@ public static class ThreadBorderRouterManagementCluster extends BaseChipCluster private static final long BORDER_AGENT_I_D_ATTRIBUTE_ID = 1L; private static final long THREAD_VERSION_ATTRIBUTE_ID = 2L; private static final long INTERFACE_ENABLED_ATTRIBUTE_ID = 3L; - private static final long ACTIVE_DATASET_TIMESTAMP_ATTRIBUTE_ID = 5L; + private static final long ACTIVE_DATASET_TIMESTAMP_ATTRIBUTE_ID = 4L; private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; @@ -53693,7 +54104,7 @@ public void setActiveDatasetRequest(DefaultClusterCallback callback, byte[] acti } public void setActiveDatasetRequest(DefaultClusterCallback callback, byte[] activeDataset, Optional breadcrumb, int timedInvokeTimeoutMs) { - final long commandId = 4L; + final long commandId = 3L; ArrayList elements = new ArrayList<>(); final long activeDatasetFieldID = 0L; @@ -53717,7 +54128,7 @@ public void setPendingDatasetRequest(DefaultClusterCallback callback, byte[] pen } public void setPendingDatasetRequest(DefaultClusterCallback callback, byte[] pendingDataset, int timedInvokeTimeoutMs) { - final long commandId = 5L; + final long commandId = 4L; ArrayList elements = new ArrayList<>(); final long pendingDatasetFieldID = 0L; @@ -59222,80 +59633,236 @@ public void readScheduledContentRatingsAttribute( readAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SCHEDULED_CONTENT_RATINGS_ATTRIBUTE_ID, true); + } + + public void subscribeScheduledContentRatingsAttribute( + ScheduledContentRatingsAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SCHEDULED_CONTENT_RATINGS_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SCHEDULED_CONTENT_RATINGS_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readScheduledContentRatingThresholdAttribute( + CharStringAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SCHEDULED_CONTENT_RATING_THRESHOLD_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + String value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SCHEDULED_CONTENT_RATING_THRESHOLD_ATTRIBUTE_ID, true); + } + + public void subscribeScheduledContentRatingThresholdAttribute( + CharStringAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SCHEDULED_CONTENT_RATING_THRESHOLD_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + String value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SCHEDULED_CONTENT_RATING_THRESHOLD_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readScreenDailyTimeAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SCREEN_DAILY_TIME_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SCREEN_DAILY_TIME_ATTRIBUTE_ID, true); + } + + public void subscribeScreenDailyTimeAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SCREEN_DAILY_TIME_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SCREEN_DAILY_TIME_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readRemainingScreenTimeAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, REMAINING_SCREEN_TIME_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, REMAINING_SCREEN_TIME_ATTRIBUTE_ID, true); + } + + public void subscribeRemainingScreenTimeAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, REMAINING_SCREEN_TIME_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, REMAINING_SCREEN_TIME_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readBlockUnratedAttribute( + BooleanAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, BLOCK_UNRATED_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Boolean value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, BLOCK_UNRATED_ATTRIBUTE_ID, true); + } + + public void subscribeBlockUnratedAttribute( + BooleanAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, BLOCK_UNRATED_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Boolean value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, BLOCK_UNRATED_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, SCHEDULED_CONTENT_RATINGS_ATTRIBUTE_ID, true); + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, true); } - public void subscribeScheduledContentRatingsAttribute( - ScheduledContentRatingsAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SCHEDULED_CONTENT_RATINGS_ATTRIBUTE_ID); + public void subscribeAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, SCHEDULED_CONTENT_RATINGS_ATTRIBUTE_ID, minInterval, maxInterval); + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readScheduledContentRatingThresholdAttribute( - CharStringAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SCHEDULED_CONTENT_RATING_THRESHOLD_ATTRIBUTE_ID); + public void readEventListAttribute( + EventListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - String value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, SCHEDULED_CONTENT_RATING_THRESHOLD_ATTRIBUTE_ID, true); + }, EVENT_LIST_ATTRIBUTE_ID, true); } - public void subscribeScheduledContentRatingThresholdAttribute( - CharStringAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SCHEDULED_CONTENT_RATING_THRESHOLD_ATTRIBUTE_ID); + public void subscribeEventListAttribute( + EventListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - String value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, SCHEDULED_CONTENT_RATING_THRESHOLD_ATTRIBUTE_ID, minInterval, maxInterval); + }, EVENT_LIST_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readScreenDailyTimeAttribute( - LongAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SCREEN_DAILY_TIME_ATTRIBUTE_ID); + public void readAttributeListAttribute( + AttributeListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, SCREEN_DAILY_TIME_ATTRIBUTE_ID, true); + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, true); } - public void subscribeScreenDailyTimeAttribute( - LongAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SCREEN_DAILY_TIME_ATTRIBUTE_ID); + public void subscribeAttributeListAttribute( + AttributeListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, SCREEN_DAILY_TIME_ATTRIBUTE_ID, minInterval, maxInterval); + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readRemainingScreenTimeAttribute( + public void readFeatureMapAttribute( LongAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, REMAINING_SCREEN_TIME_ATTRIBUTE_ID); + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -59303,12 +59870,12 @@ public void onSuccess(byte[] tlv) { Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, REMAINING_SCREEN_TIME_ATTRIBUTE_ID, true); + }, FEATURE_MAP_ATTRIBUTE_ID, true); } - public void subscribeRemainingScreenTimeAttribute( + public void subscribeFeatureMapAttribute( LongAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, REMAINING_SCREEN_TIME_ATTRIBUTE_ID); + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -59316,33 +59883,122 @@ public void onSuccess(byte[] tlv) { Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, REMAINING_SCREEN_TIME_ATTRIBUTE_ID, minInterval, maxInterval); + }, FEATURE_MAP_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readBlockUnratedAttribute( - BooleanAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, BLOCK_UNRATED_ATTRIBUTE_ID); + public void readClusterRevisionAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - Boolean value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, BLOCK_UNRATED_ATTRIBUTE_ID, true); + }, CLUSTER_REVISION_ATTRIBUTE_ID, true); } - public void subscribeBlockUnratedAttribute( - BooleanAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, BLOCK_UNRATED_ATTRIBUTE_ID); + public void subscribeClusterRevisionAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - Boolean value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, BLOCK_UNRATED_ATTRIBUTE_ID, minInterval, maxInterval); + }, CLUSTER_REVISION_ATTRIBUTE_ID, minInterval, maxInterval); + } + } + + public static class ContentAppObserverCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 1296L; + + private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; + private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; + private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; + private static final long ATTRIBUTE_LIST_ATTRIBUTE_ID = 65531L; + private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L; + private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L; + + public ContentAppObserverCluster(long devicePtr, int endpointId) { + super(devicePtr, endpointId, CLUSTER_ID); + } + + @Override + @Deprecated + public long initWithDevice(long devicePtr, int endpointId) { + return 0L; + } + + public void contentAppMessage(ContentAppMessageResponseCallback callback, Optional data, String encodingHint) { + contentAppMessage(callback, data, encodingHint, 0); + } + + public void contentAppMessage(ContentAppMessageResponseCallback callback, Optional data, String encodingHint, int timedInvokeTimeoutMs) { + final long commandId = 0L; + + ArrayList elements = new ArrayList<>(); + final long dataFieldID = 0L; + BaseTLVType datatlvValue = data.map((nonOptionaldata) -> new StringType(nonOptionaldata)).orElse(new EmptyType()); + elements.add(new StructElement(dataFieldID, datatlvValue)); + + final long encodingHintFieldID = 1L; + BaseTLVType encodingHinttlvValue = new StringType(encodingHint); + elements.add(new StructElement(encodingHintFieldID, encodingHinttlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long statusFieldID = 0L; + Integer status = null; + final long dataFieldID = 1L; + Optional data = Optional.empty(); + final long encodingHintFieldID = 2L; + Optional encodingHint = Optional.empty(); + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == statusFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + status = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == dataFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + data = Optional.of(castingValue.value(String.class)); + } + } else if (element.contextTagNum() == encodingHintFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + encodingHint = Optional.of(castingValue.value(String.class)); + } + } + } + callback.onSuccess(status, data, encodingHint); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public interface ContentAppMessageResponseCallback extends BaseClusterCallback { + void onSuccess(Integer status, Optional data, Optional encodingHint); + } + + public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AcceptedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface EventListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AttributeListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); } public void readGeneratedCommandListAttribute( @@ -59502,9 +60158,10 @@ public void onSuccess(byte[] tlv) { } } - public static class ContentAppObserverCluster extends BaseChipCluster { - public static final long CLUSTER_ID = 1296L; + public static class CommissionerControlCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 1873L; + private static final long SUPPORTED_DEVICE_CATEGORIES_ATTRIBUTE_ID = 0L; private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; @@ -59512,7 +60169,7 @@ public static class ContentAppObserverCluster extends BaseChipCluster { private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L; private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L; - public ContentAppObserverCluster(long devicePtr, int endpointId) { + public CommissionerControlCluster(long devicePtr, int endpointId) { super(devicePtr, endpointId, CLUSTER_ID); } @@ -59522,56 +60179,110 @@ public long initWithDevice(long devicePtr, int endpointId) { return 0L; } - public void contentAppMessage(ContentAppMessageResponseCallback callback, Optional data, String encodingHint) { - contentAppMessage(callback, data, encodingHint, 0); + public void requestCommissioningApproval(DefaultClusterCallback callback, Long requestId, Integer vendorId, Integer productId, Optional label) { + requestCommissioningApproval(callback, requestId, vendorId, productId, label, 0); } - public void contentAppMessage(ContentAppMessageResponseCallback callback, Optional data, String encodingHint, int timedInvokeTimeoutMs) { + public void requestCommissioningApproval(DefaultClusterCallback callback, Long requestId, Integer vendorId, Integer productId, Optional label, int timedInvokeTimeoutMs) { final long commandId = 0L; ArrayList elements = new ArrayList<>(); - final long dataFieldID = 0L; - BaseTLVType datatlvValue = data.map((nonOptionaldata) -> new StringType(nonOptionaldata)).orElse(new EmptyType()); - elements.add(new StructElement(dataFieldID, datatlvValue)); + final long requestIdFieldID = 0L; + BaseTLVType requestIdtlvValue = new UIntType(requestId); + elements.add(new StructElement(requestIdFieldID, requestIdtlvValue)); - final long encodingHintFieldID = 1L; - BaseTLVType encodingHinttlvValue = new StringType(encodingHint); - elements.add(new StructElement(encodingHintFieldID, encodingHinttlvValue)); + final long vendorIdFieldID = 1L; + BaseTLVType vendorIdtlvValue = new UIntType(vendorId); + elements.add(new StructElement(vendorIdFieldID, vendorIdtlvValue)); + + final long productIdFieldID = 2L; + BaseTLVType productIdtlvValue = new UIntType(productId); + elements.add(new StructElement(productIdFieldID, productIdtlvValue)); + + final long labelFieldID = 3L; + BaseTLVType labeltlvValue = label.map((nonOptionallabel) -> new StringType(nonOptionallabel)).orElse(new EmptyType()); + elements.add(new StructElement(labelFieldID, labeltlvValue)); StructType commandArgs = new StructType(elements); invoke(new InvokeCallbackImpl(callback) { @Override public void onResponse(StructType invokeStructValue) { - final long statusFieldID = 0L; - Integer status = null; - final long dataFieldID = 1L; - Optional data = Optional.empty(); - final long encodingHintFieldID = 2L; - Optional encodingHint = Optional.empty(); + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public void commissionNode(ReverseOpenCommissioningWindowCallback callback, Long requestId, Integer responseTimeoutSeconds, Optional ipAddress, Optional port) { + commissionNode(callback, requestId, responseTimeoutSeconds, ipAddress, port, 0); + } + + public void commissionNode(ReverseOpenCommissioningWindowCallback callback, Long requestId, Integer responseTimeoutSeconds, Optional ipAddress, Optional port, int timedInvokeTimeoutMs) { + final long commandId = 1L; + + ArrayList elements = new ArrayList<>(); + final long requestIdFieldID = 0L; + BaseTLVType requestIdtlvValue = new UIntType(requestId); + elements.add(new StructElement(requestIdFieldID, requestIdtlvValue)); + + final long responseTimeoutSecondsFieldID = 1L; + BaseTLVType responseTimeoutSecondstlvValue = new UIntType(responseTimeoutSeconds); + elements.add(new StructElement(responseTimeoutSecondsFieldID, responseTimeoutSecondstlvValue)); + + final long ipAddressFieldID = 2L; + BaseTLVType ipAddresstlvValue = ipAddress.map((nonOptionalipAddress) -> new ByteArrayType(nonOptionalipAddress)).orElse(new EmptyType()); + elements.add(new StructElement(ipAddressFieldID, ipAddresstlvValue)); + + final long portFieldID = 3L; + BaseTLVType porttlvValue = port.map((nonOptionalport) -> new UIntType(nonOptionalport)).orElse(new EmptyType()); + elements.add(new StructElement(portFieldID, porttlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long commissioningTimeoutFieldID = 0L; + Integer commissioningTimeout = null; + final long PAKEPasscodeVerifierFieldID = 1L; + byte[] PAKEPasscodeVerifier = null; + final long discriminatorFieldID = 2L; + Integer discriminator = null; + final long iterationsFieldID = 3L; + Long iterations = null; + final long saltFieldID = 4L; + byte[] salt = null; for (StructElement element: invokeStructValue.value()) { - if (element.contextTagNum() == statusFieldID) { + if (element.contextTagNum() == commissioningTimeoutFieldID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { UIntType castingValue = element.value(UIntType.class); - status = castingValue.value(Integer.class); + commissioningTimeout = castingValue.value(Integer.class); } - } else if (element.contextTagNum() == dataFieldID) { - if (element.value(BaseTLVType.class).type() == TLVType.String) { - StringType castingValue = element.value(StringType.class); - data = Optional.of(castingValue.value(String.class)); + } else if (element.contextTagNum() == PAKEPasscodeVerifierFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.ByteArray) { + ByteArrayType castingValue = element.value(ByteArrayType.class); + PAKEPasscodeVerifier = castingValue.value(byte[].class); } - } else if (element.contextTagNum() == encodingHintFieldID) { - if (element.value(BaseTLVType.class).type() == TLVType.String) { - StringType castingValue = element.value(StringType.class); - encodingHint = Optional.of(castingValue.value(String.class)); + } else if (element.contextTagNum() == discriminatorFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + discriminator = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == iterationsFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + iterations = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == saltFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.ByteArray) { + ByteArrayType castingValue = element.value(ByteArrayType.class); + salt = castingValue.value(byte[].class); } } } - callback.onSuccess(status, data, encodingHint); + callback.onSuccess(commissioningTimeout, PAKEPasscodeVerifier, discriminator, iterations, salt); }}, commandId, commandArgs, timedInvokeTimeoutMs); } - public interface ContentAppMessageResponseCallback extends BaseClusterCallback { - void onSuccess(Integer status, Optional data, Optional encodingHint); + public interface ReverseOpenCommissioningWindowCallback extends BaseClusterCallback { + void onSuccess(Integer commissioningTimeout, byte[] PAKEPasscodeVerifier, Integer discriminator, Long iterations, byte[] salt); } public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { @@ -59590,6 +60301,32 @@ public interface AttributeListAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } + public void readSupportedDeviceCategoriesAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_DEVICE_CATEGORIES_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SUPPORTED_DEVICE_CATEGORIES_ATTRIBUTE_ID, true); + } + + public void subscribeSupportedDeviceCategoriesAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_DEVICE_CATEGORIES_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SUPPORTED_DEVICE_CATEGORIES_ATTRIBUTE_ID, minInterval, maxInterval); + } + public void readGeneratedCommandListAttribute( GeneratedCommandListAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java index d25d80c3f791fc..d256c91c32d9ed 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java @@ -4323,18 +4323,22 @@ public static class EnergyEvseClusterEnergyTransferStartedEvent { public Long sessionID; public Integer state; public Long maximumCurrent; + public Optional maximumDischargeCurrent; private static final long SESSION_I_D_ID = 0L; private static final long STATE_ID = 1L; private static final long MAXIMUM_CURRENT_ID = 2L; + private static final long MAXIMUM_DISCHARGE_CURRENT_ID = 3L; public EnergyEvseClusterEnergyTransferStartedEvent( Long sessionID, Integer state, - Long maximumCurrent + Long maximumCurrent, + Optional maximumDischargeCurrent ) { this.sessionID = sessionID; this.state = state; this.maximumCurrent = maximumCurrent; + this.maximumDischargeCurrent = maximumDischargeCurrent; } public StructType encodeTlv() { @@ -4342,6 +4346,7 @@ public StructType encodeTlv() { values.add(new StructElement(SESSION_I_D_ID, new UIntType(sessionID))); values.add(new StructElement(STATE_ID, new UIntType(state))); values.add(new StructElement(MAXIMUM_CURRENT_ID, new IntType(maximumCurrent))); + values.add(new StructElement(MAXIMUM_DISCHARGE_CURRENT_ID, maximumDischargeCurrent.map((nonOptionalmaximumDischargeCurrent) -> new IntType(nonOptionalmaximumDischargeCurrent)).orElse(new EmptyType()))); return new StructType(values); } @@ -4353,6 +4358,7 @@ public static EnergyEvseClusterEnergyTransferStartedEvent decodeTlv(BaseTLVType Long sessionID = null; Integer state = null; Long maximumCurrent = null; + Optional maximumDischargeCurrent = Optional.empty(); for (StructElement element: ((StructType)tlvValue).value()) { if (element.contextTagNum() == SESSION_I_D_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { @@ -4369,12 +4375,18 @@ public static EnergyEvseClusterEnergyTransferStartedEvent decodeTlv(BaseTLVType IntType castingValue = element.value(IntType.class); maximumCurrent = castingValue.value(Long.class); } + } else if (element.contextTagNum() == MAXIMUM_DISCHARGE_CURRENT_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Int) { + IntType castingValue = element.value(IntType.class); + maximumDischargeCurrent = Optional.of(castingValue.value(Long.class)); + } } } return new EnergyEvseClusterEnergyTransferStartedEvent( sessionID, state, - maximumCurrent + maximumCurrent, + maximumDischargeCurrent ); } @@ -4391,6 +4403,9 @@ public String toString() { output.append("\tmaximumCurrent: "); output.append(maximumCurrent); output.append("\n"); + output.append("\tmaximumDischargeCurrent: "); + output.append(maximumDischargeCurrent); + output.append("\n"); output.append("}\n"); return output.toString(); } @@ -4400,21 +4415,25 @@ public static class EnergyEvseClusterEnergyTransferStoppedEvent { public Integer state; public Integer reason; public Long energyTransferred; + public Optional energyDischarged; private static final long SESSION_I_D_ID = 0L; private static final long STATE_ID = 1L; private static final long REASON_ID = 2L; private static final long ENERGY_TRANSFERRED_ID = 4L; + private static final long ENERGY_DISCHARGED_ID = 5L; public EnergyEvseClusterEnergyTransferStoppedEvent( Long sessionID, Integer state, Integer reason, - Long energyTransferred + Long energyTransferred, + Optional energyDischarged ) { this.sessionID = sessionID; this.state = state; this.reason = reason; this.energyTransferred = energyTransferred; + this.energyDischarged = energyDischarged; } public StructType encodeTlv() { @@ -4423,6 +4442,7 @@ public StructType encodeTlv() { values.add(new StructElement(STATE_ID, new UIntType(state))); values.add(new StructElement(REASON_ID, new UIntType(reason))); values.add(new StructElement(ENERGY_TRANSFERRED_ID, new IntType(energyTransferred))); + values.add(new StructElement(ENERGY_DISCHARGED_ID, energyDischarged.map((nonOptionalenergyDischarged) -> new IntType(nonOptionalenergyDischarged)).orElse(new EmptyType()))); return new StructType(values); } @@ -4435,6 +4455,7 @@ public static EnergyEvseClusterEnergyTransferStoppedEvent decodeTlv(BaseTLVType Integer state = null; Integer reason = null; Long energyTransferred = null; + Optional energyDischarged = Optional.empty(); for (StructElement element: ((StructType)tlvValue).value()) { if (element.contextTagNum() == SESSION_I_D_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { @@ -4456,13 +4477,19 @@ public static EnergyEvseClusterEnergyTransferStoppedEvent decodeTlv(BaseTLVType IntType castingValue = element.value(IntType.class); energyTransferred = castingValue.value(Long.class); } + } else if (element.contextTagNum() == ENERGY_DISCHARGED_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Int) { + IntType castingValue = element.value(IntType.class); + energyDischarged = Optional.of(castingValue.value(Long.class)); + } } } return new EnergyEvseClusterEnergyTransferStoppedEvent( sessionID, state, reason, - energyTransferred + energyTransferred, + energyDischarged ); } @@ -4482,6 +4509,9 @@ public String toString() { output.append("\tenergyTransferred: "); output.append(energyTransferred); output.append("\n"); + output.append("\tenergyDischarged: "); + output.append(energyDischarged); + output.append("\n"); output.append("}\n"); return output.toString(); } @@ -5946,6 +5976,97 @@ public String toString() { return output.toString(); } } +public static class CommissionerControlClusterCommissioningRequestResultEvent { + public Long requestId; + public Long clientNodeId; + public Integer statusCode; + public Integer fabricIndex; + private static final long REQUEST_ID_ID = 0L; + private static final long CLIENT_NODE_ID_ID = 1L; + private static final long STATUS_CODE_ID = 2L; + private static final long FABRIC_INDEX_ID = 254L; + + public CommissionerControlClusterCommissioningRequestResultEvent( + Long requestId, + Long clientNodeId, + Integer statusCode, + Integer fabricIndex + ) { + this.requestId = requestId; + this.clientNodeId = clientNodeId; + this.statusCode = statusCode; + this.fabricIndex = fabricIndex; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(REQUEST_ID_ID, new UIntType(requestId))); + values.add(new StructElement(CLIENT_NODE_ID_ID, new UIntType(clientNodeId))); + values.add(new StructElement(STATUS_CODE_ID, new UIntType(statusCode))); + values.add(new StructElement(FABRIC_INDEX_ID, new UIntType(fabricIndex))); + + return new StructType(values); + } + + public static CommissionerControlClusterCommissioningRequestResultEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Long requestId = null; + Long clientNodeId = null; + Integer statusCode = null; + Integer fabricIndex = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == REQUEST_ID_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + requestId = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == CLIENT_NODE_ID_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + clientNodeId = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == STATUS_CODE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + statusCode = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == FABRIC_INDEX_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + fabricIndex = castingValue.value(Integer.class); + } + } + } + return new CommissionerControlClusterCommissioningRequestResultEvent( + requestId, + clientNodeId, + statusCode, + fabricIndex + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("CommissionerControlClusterCommissioningRequestResultEvent {\n"); + output.append("\trequestId: "); + output.append(requestId); + output.append("\n"); + output.append("\tclientNodeId: "); + output.append(clientNodeId); + output.append("\n"); + output.append("\tstatusCode: "); + output.append(statusCode); + output.append("\n"); + output.append("\tfabricIndex: "); + output.append(fabricIndex); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} public static class UnitTestingClusterTestEventEvent { public Integer arg1; public Integer arg2; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index eb51a558634fe4..698ee556bb324b 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -229,6 +229,9 @@ public static BaseCluster getCluster(long clusterId) { if (clusterId == ElectricalEnergyMeasurement.ID) { return new ElectricalEnergyMeasurement(); } + if (clusterId == WaterHeaterManagement.ID) { + return new WaterHeaterManagement(); + } if (clusterId == DemandResponseLoadControl.ID) { return new DemandResponseLoadControl(); } @@ -382,6 +385,9 @@ public static BaseCluster getCluster(long clusterId) { if (clusterId == ContentAppObserver.ID) { return new ContentAppObserver(); } + if (clusterId == CommissionerControl.ID) { + return new CommissionerControl(); + } if (clusterId == ElectricalMeasurement.ID) { return new ElectricalMeasurement(); } @@ -9300,6 +9306,131 @@ public long getCommandID(String name) throws IllegalArgumentException { return Command.valueOf(name).getID(); } } + public static class WaterHeaterManagement implements BaseCluster { + public static final long ID = 148L; + public long getID() { + return ID; + } + + public enum Attribute { + HeaterTypes(0L), + HeatDemand(1L), + TankVolume(2L), + EstimatedHeatRequired(3L), + TankPercentage(4L), + BoostState(5L), + GeneratedCommandList(65528L), + AcceptedCommandList(65529L), + EventList(65530L), + AttributeList(65531L), + FeatureMap(65532L), + ClusterRevision(65533L),; + private final long id; + Attribute(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Attribute value(long id) throws NoSuchFieldError { + for (Attribute attribute : Attribute.values()) { + if (attribute.getID() == id) { + return attribute; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Event {; + private final long id; + Event(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Event value(long id) throws NoSuchFieldError { + for (Event event : Event.values()) { + if (event.getID() == id) { + return event; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Command { + Boost(0L), + CancelBoost(1L),; + private final long id; + Command(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Command value(long id) throws NoSuchFieldError { + for (Command command : Command.values()) { + if (command.getID() == id) { + return command; + } + } + throw new NoSuchFieldError(); + } + }public enum BoostCommandField {Duration(0),OneShot(1),EmergencyBoost(2),TemporarySetpoint(3),TargetPercentage(4),TargetReheat(5),; + private final int id; + BoostCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static BoostCommandField value(int id) throws NoSuchFieldError { + for (BoostCommandField field : BoostCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }@Override + public String getAttributeName(long id) throws NoSuchFieldError { + return Attribute.value(id).toString(); + } + + @Override + public String getEventName(long id) throws NoSuchFieldError { + return Event.value(id).toString(); + } + + @Override + public String getCommandName(long id) throws NoSuchFieldError { + return Command.value(id).toString(); + } + + @Override + public long getAttributeID(String name) throws IllegalArgumentException { + return Attribute.valueOf(name).getID(); + } + + @Override + public long getEventID(String name) throws IllegalArgumentException { + return Event.valueOf(name).getID(); + } + + @Override + public long getCommandID(String name) throws IllegalArgumentException { + return Command.valueOf(name).getID(); + } + } public static class DemandResponseLoadControl implements BaseCluster { public static final long ID = 150L; public long getID() { @@ -14565,7 +14696,7 @@ public enum Attribute { BorderAgentID(1L), ThreadVersion(2L), InterfaceEnabled(3L), - ActiveDatasetTimestamp(5L), + ActiveDatasetTimestamp(4L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), EventList(65530L), @@ -14614,8 +14745,8 @@ public static Event value(long id) throws NoSuchFieldError { public enum Command { GetActiveDatasetRequest(0L), GetPendingDatasetRequest(1L), - SetActiveDatasetRequest(4L), - SetPendingDatasetRequest(5L),; + SetActiveDatasetRequest(3L), + SetPendingDatasetRequest(4L),; private final long id; Command(long id) { this.id = id; @@ -16910,6 +17041,144 @@ public long getCommandID(String name) throws IllegalArgumentException { return Command.valueOf(name).getID(); } } + public static class CommissionerControl implements BaseCluster { + public static final long ID = 1873L; + public long getID() { + return ID; + } + + public enum Attribute { + SupportedDeviceCategories(0L), + GeneratedCommandList(65528L), + AcceptedCommandList(65529L), + EventList(65530L), + AttributeList(65531L), + FeatureMap(65532L), + ClusterRevision(65533L),; + private final long id; + Attribute(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Attribute value(long id) throws NoSuchFieldError { + for (Attribute attribute : Attribute.values()) { + if (attribute.getID() == id) { + return attribute; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Event { + CommissioningRequestResult(0L),; + private final long id; + Event(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Event value(long id) throws NoSuchFieldError { + for (Event event : Event.values()) { + if (event.getID() == id) { + return event; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Command { + RequestCommissioningApproval(0L), + CommissionNode(1L),; + private final long id; + Command(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Command value(long id) throws NoSuchFieldError { + for (Command command : Command.values()) { + if (command.getID() == id) { + return command; + } + } + throw new NoSuchFieldError(); + } + }public enum RequestCommissioningApprovalCommandField {RequestId(0),VendorId(1),ProductId(2),Label(3),; + private final int id; + RequestCommissioningApprovalCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static RequestCommissioningApprovalCommandField value(int id) throws NoSuchFieldError { + for (RequestCommissioningApprovalCommandField field : RequestCommissioningApprovalCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }public enum CommissionNodeCommandField {RequestId(0),ResponseTimeoutSeconds(1),IpAddress(2),Port(3),; + private final int id; + CommissionNodeCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static CommissionNodeCommandField value(int id) throws NoSuchFieldError { + for (CommissionNodeCommandField field : CommissionNodeCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }@Override + public String getAttributeName(long id) throws NoSuchFieldError { + return Attribute.value(id).toString(); + } + + @Override + public String getEventName(long id) throws NoSuchFieldError { + return Event.value(id).toString(); + } + + @Override + public String getCommandName(long id) throws NoSuchFieldError { + return Command.value(id).toString(); + } + + @Override + public long getAttributeID(String name) throws IllegalArgumentException { + return Attribute.valueOf(name).getID(); + } + + @Override + public long getEventID(String name) throws IllegalArgumentException { + return Event.valueOf(name).getID(); + } + + @Override + public long getCommandID(String name) throws IllegalArgumentException { + return Command.valueOf(name).getID(); + } + } public static class ElectricalMeasurement implements BaseCluster { public static final long ID = 2820L; public long getID() { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 00ccd333d9ff76..06b24ad59e09af 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -10601,6 +10601,90 @@ public void onError(Exception ex) { } } + public static class DelegatedWaterHeaterManagementClusterGeneratedCommandListAttributeCallback implements ChipClusters.WaterHeaterManagementCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWaterHeaterManagementClusterAcceptedCommandListAttributeCallback implements ChipClusters.WaterHeaterManagementCluster.AcceptedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWaterHeaterManagementClusterEventListAttributeCallback implements ChipClusters.WaterHeaterManagementCluster.EventListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWaterHeaterManagementClusterAttributeListAttributeCallback implements ChipClusters.WaterHeaterManagementCluster.AttributeListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + public static class DelegatedDemandResponseLoadControlClusterLoadControlProgramsAttributeCallback implements ChipClusters.DemandResponseLoadControlCluster.LoadControlProgramsAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -19855,6 +19939,120 @@ public void onError(Exception ex) { } } + + public static class DelegatedCommissionerControlClusterReverseOpenCommissioningWindowCallback implements ChipClusters.CommissionerControlCluster.ReverseOpenCommissioningWindowCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(Integer commissioningTimeout, byte[] PAKEPasscodeVerifier, Integer discriminator, Long iterations, byte[] salt) { + Map responseValues = new LinkedHashMap<>(); + + CommandResponseInfo commissioningTimeoutResponseValue = new CommandResponseInfo("commissioningTimeout", "Integer"); + responseValues.put(commissioningTimeoutResponseValue, commissioningTimeout); + CommandResponseInfo PAKEPasscodeVerifierResponseValue = new CommandResponseInfo("PAKEPasscodeVerifier", "byte[]"); + responseValues.put(PAKEPasscodeVerifierResponseValue, PAKEPasscodeVerifier); + CommandResponseInfo discriminatorResponseValue = new CommandResponseInfo("discriminator", "Integer"); + responseValues.put(discriminatorResponseValue, discriminator); + CommandResponseInfo iterationsResponseValue = new CommandResponseInfo("iterations", "Long"); + responseValues.put(iterationsResponseValue, iterations); + CommandResponseInfo saltResponseValue = new CommandResponseInfo("salt", "byte[]"); + responseValues.put(saltResponseValue, salt); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } + public static class DelegatedCommissionerControlClusterGeneratedCommandListAttributeCallback implements ChipClusters.CommissionerControlCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedCommissionerControlClusterAcceptedCommandListAttributeCallback implements ChipClusters.CommissionerControlCluster.AcceptedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedCommissionerControlClusterEventListAttributeCallback implements ChipClusters.CommissionerControlCluster.EventListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedCommissionerControlClusterAttributeListAttributeCallback implements ChipClusters.CommissionerControlCluster.AttributeListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + public static class DelegatedElectricalMeasurementClusterGeneratedCommandListAttributeCallback implements ChipClusters.ElectricalMeasurementCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -21748,6 +21946,10 @@ public Map initializeClusterMap() { (ptr, endpointId) -> new ChipClusters.ElectricalEnergyMeasurementCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("electricalEnergyMeasurement", electricalEnergyMeasurementClusterInfo); + ClusterInfo waterHeaterManagementClusterInfo = new ClusterInfo( + (ptr, endpointId) -> new ChipClusters.WaterHeaterManagementCluster(ptr, endpointId), new HashMap<>()); + clusterMap.put("waterHeaterManagement", waterHeaterManagementClusterInfo); + ClusterInfo demandResponseLoadControlClusterInfo = new ClusterInfo( (ptr, endpointId) -> new ChipClusters.DemandResponseLoadControlCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("demandResponseLoadControl", demandResponseLoadControlClusterInfo); @@ -21952,6 +22154,10 @@ public Map initializeClusterMap() { (ptr, endpointId) -> new ChipClusters.ContentAppObserverCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("contentAppObserver", contentAppObserverClusterInfo); + ClusterInfo commissionerControlClusterInfo = new ClusterInfo( + (ptr, endpointId) -> new ChipClusters.CommissionerControlCluster(ptr, endpointId), new HashMap<>()); + clusterMap.put("commissionerControl", commissionerControlClusterInfo); + ClusterInfo electricalMeasurementClusterInfo = new ClusterInfo( (ptr, endpointId) -> new ChipClusters.ElectricalMeasurementCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("electricalMeasurement", electricalMeasurementClusterInfo); @@ -22039,6 +22245,7 @@ public void combineCommand(Map destination, Map destination, Map> getCommandMap() { commandMap.put("electricalEnergyMeasurement", electricalEnergyMeasurementClusterInteractionInfoMap); + Map waterHeaterManagementClusterInteractionInfoMap = new LinkedHashMap<>(); + + Map waterHeaterManagementboostCommandParams = new LinkedHashMap(); + + CommandParameterInfo waterHeaterManagementboostdurationCommandParameterInfo = new CommandParameterInfo("duration", Long.class, Long.class); + waterHeaterManagementboostCommandParams.put("duration",waterHeaterManagementboostdurationCommandParameterInfo); + + CommandParameterInfo waterHeaterManagementboostoneShotCommandParameterInfo = new CommandParameterInfo("oneShot", Optional.class, Boolean.class); + waterHeaterManagementboostCommandParams.put("oneShot",waterHeaterManagementboostoneShotCommandParameterInfo); + + CommandParameterInfo waterHeaterManagementboostemergencyBoostCommandParameterInfo = new CommandParameterInfo("emergencyBoost", Optional.class, Boolean.class); + waterHeaterManagementboostCommandParams.put("emergencyBoost",waterHeaterManagementboostemergencyBoostCommandParameterInfo); + + CommandParameterInfo waterHeaterManagementboosttemporarySetpointCommandParameterInfo = new CommandParameterInfo("temporarySetpoint", Optional.class, Integer.class); + waterHeaterManagementboostCommandParams.put("temporarySetpoint",waterHeaterManagementboosttemporarySetpointCommandParameterInfo); + + CommandParameterInfo waterHeaterManagementboosttargetPercentageCommandParameterInfo = new CommandParameterInfo("targetPercentage", Optional.class, Integer.class); + waterHeaterManagementboostCommandParams.put("targetPercentage",waterHeaterManagementboosttargetPercentageCommandParameterInfo); + + CommandParameterInfo waterHeaterManagementboosttargetReheatCommandParameterInfo = new CommandParameterInfo("targetReheat", Optional.class, Integer.class); + waterHeaterManagementboostCommandParams.put("targetReheat",waterHeaterManagementboosttargetReheatCommandParameterInfo); + InteractionInfo waterHeaterManagementboostInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterManagementCluster) cluster) + .boost((DefaultClusterCallback) callback + , (Long) + commandArguments.get("duration") + , (Optional) + commandArguments.get("oneShot") + , (Optional) + commandArguments.get("emergencyBoost") + , (Optional) + commandArguments.get("temporarySetpoint") + , (Optional) + commandArguments.get("targetPercentage") + , (Optional) + commandArguments.get("targetReheat") + ); + }, + () -> new DelegatedDefaultClusterCallback(), + waterHeaterManagementboostCommandParams + ); + waterHeaterManagementClusterInteractionInfoMap.put("boost", waterHeaterManagementboostInteractionInfo); + + Map waterHeaterManagementcancelBoostCommandParams = new LinkedHashMap(); + InteractionInfo waterHeaterManagementcancelBoostInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterManagementCluster) cluster) + .cancelBoost((DefaultClusterCallback) callback + ); + }, + () -> new DelegatedDefaultClusterCallback(), + waterHeaterManagementcancelBoostCommandParams + ); + waterHeaterManagementClusterInteractionInfoMap.put("cancelBoost", waterHeaterManagementcancelBoostInteractionInfo); + + commandMap.put("waterHeaterManagement", waterHeaterManagementClusterInteractionInfoMap); + Map demandResponseLoadControlClusterInteractionInfoMap = new LinkedHashMap<>(); Map demandResponseLoadControlregisterLoadControlProgramRequestCommandParams = new LinkedHashMap(); @@ -28212,6 +28478,78 @@ public Map> getCommandMap() { commandMap.put("contentAppObserver", contentAppObserverClusterInteractionInfoMap); + Map commissionerControlClusterInteractionInfoMap = new LinkedHashMap<>(); + + Map commissionerControlrequestCommissioningApprovalCommandParams = new LinkedHashMap(); + + CommandParameterInfo commissionerControlrequestCommissioningApprovalrequestIdCommandParameterInfo = new CommandParameterInfo("requestId", Long.class, Long.class); + commissionerControlrequestCommissioningApprovalCommandParams.put("requestId",commissionerControlrequestCommissioningApprovalrequestIdCommandParameterInfo); + + CommandParameterInfo commissionerControlrequestCommissioningApprovalvendorIdCommandParameterInfo = new CommandParameterInfo("vendorId", Integer.class, Integer.class); + commissionerControlrequestCommissioningApprovalCommandParams.put("vendorId",commissionerControlrequestCommissioningApprovalvendorIdCommandParameterInfo); + + CommandParameterInfo commissionerControlrequestCommissioningApprovalproductIdCommandParameterInfo = new CommandParameterInfo("productId", Integer.class, Integer.class); + commissionerControlrequestCommissioningApprovalCommandParams.put("productId",commissionerControlrequestCommissioningApprovalproductIdCommandParameterInfo); + + CommandParameterInfo commissionerControlrequestCommissioningApprovallabelCommandParameterInfo = new CommandParameterInfo("label", Optional.class, String.class); + commissionerControlrequestCommissioningApprovalCommandParams.put("label",commissionerControlrequestCommissioningApprovallabelCommandParameterInfo); + InteractionInfo commissionerControlrequestCommissioningApprovalInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster) + .requestCommissioningApproval((DefaultClusterCallback) callback + , (Long) + commandArguments.get("requestId") + , (Integer) + commandArguments.get("vendorId") + , (Integer) + commandArguments.get("productId") + , (Optional) + commandArguments.get("label") + ); + }, + () -> new DelegatedDefaultClusterCallback(), + commissionerControlrequestCommissioningApprovalCommandParams + ); + commissionerControlClusterInteractionInfoMap.put("requestCommissioningApproval", commissionerControlrequestCommissioningApprovalInteractionInfo); + + Map commissionerControlcommissionNodeCommandParams = new LinkedHashMap(); + + CommandParameterInfo commissionerControlcommissionNoderequestIdCommandParameterInfo = new CommandParameterInfo("requestId", Long.class, Long.class); + commissionerControlcommissionNodeCommandParams.put("requestId",commissionerControlcommissionNoderequestIdCommandParameterInfo); + + CommandParameterInfo commissionerControlcommissionNoderesponseTimeoutSecondsCommandParameterInfo = new CommandParameterInfo("responseTimeoutSeconds", Integer.class, Integer.class); + commissionerControlcommissionNodeCommandParams.put("responseTimeoutSeconds",commissionerControlcommissionNoderesponseTimeoutSecondsCommandParameterInfo); + + CommandParameterInfo commissionerControlcommissionNodeipAddressCommandParameterInfo = new CommandParameterInfo("ipAddress", Optional.class, byte[].class); + commissionerControlcommissionNodeCommandParams.put("ipAddress",commissionerControlcommissionNodeipAddressCommandParameterInfo); + + CommandParameterInfo commissionerControlcommissionNodeportCommandParameterInfo = new CommandParameterInfo("port", Optional.class, Integer.class); + commissionerControlcommissionNodeCommandParams.put("port",commissionerControlcommissionNodeportCommandParameterInfo); + InteractionInfo commissionerControlcommissionNodeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster) + .commissionNode((ChipClusters.CommissionerControlCluster.ReverseOpenCommissioningWindowCallback) callback + , (Long) + commandArguments.get("requestId") + + , (Integer) + commandArguments.get("responseTimeoutSeconds") + + , (Optional) + commandArguments.get("ipAddress") + + , (Optional) + commandArguments.get("port") + + ); + }, + () -> new DelegatedCommissionerControlClusterReverseOpenCommissioningWindowCallback(), + commissionerControlcommissionNodeCommandParams + ); + commissionerControlClusterInteractionInfoMap.put("commissionNode", commissionerControlcommissionNodeInteractionInfo); + + commandMap.put("commissionerControl", commissionerControlClusterInteractionInfoMap); + Map electricalMeasurementClusterInteractionInfoMap = new LinkedHashMap<>(); Map electricalMeasurementgetProfileInfoCommandCommandParams = new LinkedHashMap(); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index cbf57969d6f96f..a15dca9774da6b 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -9313,6 +9313,142 @@ private static Map readElectricalEnergyMeasurementInter return result; } + private static Map readWaterHeaterManagementInteractionInfo() { + Map result = new LinkedHashMap<>();Map readWaterHeaterManagementHeaterTypesCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterManagementHeaterTypesAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterManagementCluster) cluster).readHeaterTypesAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readWaterHeaterManagementHeaterTypesCommandParams + ); + result.put("readHeaterTypesAttribute", readWaterHeaterManagementHeaterTypesAttributeInteractionInfo); + Map readWaterHeaterManagementHeatDemandCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterManagementHeatDemandAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterManagementCluster) cluster).readHeatDemandAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readWaterHeaterManagementHeatDemandCommandParams + ); + result.put("readHeatDemandAttribute", readWaterHeaterManagementHeatDemandAttributeInteractionInfo); + Map readWaterHeaterManagementTankVolumeCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterManagementTankVolumeAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterManagementCluster) cluster).readTankVolumeAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readWaterHeaterManagementTankVolumeCommandParams + ); + result.put("readTankVolumeAttribute", readWaterHeaterManagementTankVolumeAttributeInteractionInfo); + Map readWaterHeaterManagementEstimatedHeatRequiredCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterManagementEstimatedHeatRequiredAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterManagementCluster) cluster).readEstimatedHeatRequiredAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readWaterHeaterManagementEstimatedHeatRequiredCommandParams + ); + result.put("readEstimatedHeatRequiredAttribute", readWaterHeaterManagementEstimatedHeatRequiredAttributeInteractionInfo); + Map readWaterHeaterManagementTankPercentageCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterManagementTankPercentageAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterManagementCluster) cluster).readTankPercentageAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readWaterHeaterManagementTankPercentageCommandParams + ); + result.put("readTankPercentageAttribute", readWaterHeaterManagementTankPercentageAttributeInteractionInfo); + Map readWaterHeaterManagementBoostStateCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterManagementBoostStateAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterManagementCluster) cluster).readBoostStateAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readWaterHeaterManagementBoostStateCommandParams + ); + result.put("readBoostStateAttribute", readWaterHeaterManagementBoostStateAttributeInteractionInfo); + Map readWaterHeaterManagementGeneratedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterManagementGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterManagementCluster) cluster).readGeneratedCommandListAttribute( + (ChipClusters.WaterHeaterManagementCluster.GeneratedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterManagementClusterGeneratedCommandListAttributeCallback(), + readWaterHeaterManagementGeneratedCommandListCommandParams + ); + result.put("readGeneratedCommandListAttribute", readWaterHeaterManagementGeneratedCommandListAttributeInteractionInfo); + Map readWaterHeaterManagementAcceptedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterManagementAcceptedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterManagementCluster) cluster).readAcceptedCommandListAttribute( + (ChipClusters.WaterHeaterManagementCluster.AcceptedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterManagementClusterAcceptedCommandListAttributeCallback(), + readWaterHeaterManagementAcceptedCommandListCommandParams + ); + result.put("readAcceptedCommandListAttribute", readWaterHeaterManagementAcceptedCommandListAttributeInteractionInfo); + Map readWaterHeaterManagementEventListCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterManagementEventListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterManagementCluster) cluster).readEventListAttribute( + (ChipClusters.WaterHeaterManagementCluster.EventListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterManagementClusterEventListAttributeCallback(), + readWaterHeaterManagementEventListCommandParams + ); + result.put("readEventListAttribute", readWaterHeaterManagementEventListAttributeInteractionInfo); + Map readWaterHeaterManagementAttributeListCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterManagementAttributeListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterManagementCluster) cluster).readAttributeListAttribute( + (ChipClusters.WaterHeaterManagementCluster.AttributeListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterManagementClusterAttributeListAttributeCallback(), + readWaterHeaterManagementAttributeListCommandParams + ); + result.put("readAttributeListAttribute", readWaterHeaterManagementAttributeListAttributeInteractionInfo); + Map readWaterHeaterManagementFeatureMapCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterManagementFeatureMapAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterManagementCluster) cluster).readFeatureMapAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readWaterHeaterManagementFeatureMapCommandParams + ); + result.put("readFeatureMapAttribute", readWaterHeaterManagementFeatureMapAttributeInteractionInfo); + Map readWaterHeaterManagementClusterRevisionCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterManagementClusterRevisionAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterManagementCluster) cluster).readClusterRevisionAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readWaterHeaterManagementClusterRevisionCommandParams + ); + result.put("readClusterRevisionAttribute", readWaterHeaterManagementClusterRevisionAttributeInteractionInfo); + + return result; + } private static Map readDemandResponseLoadControlInteractionInfo() { Map result = new LinkedHashMap<>();Map readDemandResponseLoadControlLoadControlProgramsCommandParams = new LinkedHashMap(); InteractionInfo readDemandResponseLoadControlLoadControlProgramsAttributeInteractionInfo = new InteractionInfo( @@ -18339,6 +18475,87 @@ private static Map readContentAppObserverInteractionInf return result; } + private static Map readCommissionerControlInteractionInfo() { + Map result = new LinkedHashMap<>();Map readCommissionerControlSupportedDeviceCategoriesCommandParams = new LinkedHashMap(); + InteractionInfo readCommissionerControlSupportedDeviceCategoriesAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster).readSupportedDeviceCategoriesAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readCommissionerControlSupportedDeviceCategoriesCommandParams + ); + result.put("readSupportedDeviceCategoriesAttribute", readCommissionerControlSupportedDeviceCategoriesAttributeInteractionInfo); + Map readCommissionerControlGeneratedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readCommissionerControlGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster).readGeneratedCommandListAttribute( + (ChipClusters.CommissionerControlCluster.GeneratedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedCommissionerControlClusterGeneratedCommandListAttributeCallback(), + readCommissionerControlGeneratedCommandListCommandParams + ); + result.put("readGeneratedCommandListAttribute", readCommissionerControlGeneratedCommandListAttributeInteractionInfo); + Map readCommissionerControlAcceptedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readCommissionerControlAcceptedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster).readAcceptedCommandListAttribute( + (ChipClusters.CommissionerControlCluster.AcceptedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedCommissionerControlClusterAcceptedCommandListAttributeCallback(), + readCommissionerControlAcceptedCommandListCommandParams + ); + result.put("readAcceptedCommandListAttribute", readCommissionerControlAcceptedCommandListAttributeInteractionInfo); + Map readCommissionerControlEventListCommandParams = new LinkedHashMap(); + InteractionInfo readCommissionerControlEventListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster).readEventListAttribute( + (ChipClusters.CommissionerControlCluster.EventListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedCommissionerControlClusterEventListAttributeCallback(), + readCommissionerControlEventListCommandParams + ); + result.put("readEventListAttribute", readCommissionerControlEventListAttributeInteractionInfo); + Map readCommissionerControlAttributeListCommandParams = new LinkedHashMap(); + InteractionInfo readCommissionerControlAttributeListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster).readAttributeListAttribute( + (ChipClusters.CommissionerControlCluster.AttributeListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedCommissionerControlClusterAttributeListAttributeCallback(), + readCommissionerControlAttributeListCommandParams + ); + result.put("readAttributeListAttribute", readCommissionerControlAttributeListAttributeInteractionInfo); + Map readCommissionerControlFeatureMapCommandParams = new LinkedHashMap(); + InteractionInfo readCommissionerControlFeatureMapAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster).readFeatureMapAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readCommissionerControlFeatureMapCommandParams + ); + result.put("readFeatureMapAttribute", readCommissionerControlFeatureMapAttributeInteractionInfo); + Map readCommissionerControlClusterRevisionCommandParams = new LinkedHashMap(); + InteractionInfo readCommissionerControlClusterRevisionAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster).readClusterRevisionAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readCommissionerControlClusterRevisionCommandParams + ); + result.put("readClusterRevisionAttribute", readCommissionerControlClusterRevisionAttributeInteractionInfo); + + return result; + } private static Map readElectricalMeasurementInteractionInfo() { Map result = new LinkedHashMap<>();Map readElectricalMeasurementMeasurementTypeCommandParams = new LinkedHashMap(); InteractionInfo readElectricalMeasurementMeasurementTypeAttributeInteractionInfo = new InteractionInfo( @@ -21000,6 +21217,7 @@ public Map> getReadAttributeMap() { put("valveConfigurationAndControl", readValveConfigurationAndControlInteractionInfo()); put("electricalPowerMeasurement", readElectricalPowerMeasurementInteractionInfo()); put("electricalEnergyMeasurement", readElectricalEnergyMeasurementInteractionInfo()); + put("waterHeaterManagement", readWaterHeaterManagementInteractionInfo()); put("demandResponseLoadControl", readDemandResponseLoadControlInteractionInfo()); put("messages", readMessagesInteractionInfo()); put("deviceEnergyManagement", readDeviceEnergyManagementInteractionInfo()); @@ -21051,6 +21269,7 @@ public Map> getReadAttributeMap() { put("accountLogin", readAccountLoginInteractionInfo()); put("contentControl", readContentControlInteractionInfo()); put("contentAppObserver", readContentAppObserverInteractionInfo()); + put("commissionerControl", readCommissionerControlInteractionInfo()); put("electricalMeasurement", readElectricalMeasurementInteractionInfo()); put("unitTesting", readUnitTestingInteractionInfo()); put("faultInjection", readFaultInjectionInteractionInfo()); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java index 86d5b9b7763dbc..635f5bf1b48830 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java @@ -1194,6 +1194,8 @@ public Map> getWriteAttributeMap() { writeAttributeMap.put("electricalPowerMeasurement", writeElectricalPowerMeasurementInteractionInfo); Map writeElectricalEnergyMeasurementInteractionInfo = new LinkedHashMap<>(); writeAttributeMap.put("electricalEnergyMeasurement", writeElectricalEnergyMeasurementInteractionInfo); + Map writeWaterHeaterManagementInteractionInfo = new LinkedHashMap<>(); + writeAttributeMap.put("waterHeaterManagement", writeWaterHeaterManagementInteractionInfo); Map writeDemandResponseLoadControlInteractionInfo = new LinkedHashMap<>(); Map writeDemandResponseLoadControlDefaultRandomStartCommandParams = new LinkedHashMap(); CommandParameterInfo demandResponseLoadControldefaultRandomStartCommandParameterInfo = @@ -3716,6 +3718,8 @@ public Map> getWriteAttributeMap() { writeAttributeMap.put("contentControl", writeContentControlInteractionInfo); Map writeContentAppObserverInteractionInfo = new LinkedHashMap<>(); writeAttributeMap.put("contentAppObserver", writeContentAppObserverInteractionInfo); + Map writeCommissionerControlInteractionInfo = new LinkedHashMap<>(); + writeAttributeMap.put("commissionerControl", writeCommissionerControlInteractionInfo); Map writeElectricalMeasurementInteractionInfo = new LinkedHashMap<>(); Map writeElectricalMeasurementAverageRmsVoltageMeasurementPeriodCommandParams = new LinkedHashMap(); CommandParameterInfo electricalMeasurementaverageRmsVoltageMeasurementPeriodCommandParameterInfo = diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt new file mode 100644 index 00000000000000..2a7a8d3c5b8ffb --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt @@ -0,0 +1,77 @@ +/* + * + * Copyright (c) 2023 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. + */ +package chip.devicecontroller.cluster.eventstructs + +import chip.devicecontroller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class CommissionerControlClusterCommissioningRequestResultEvent( + val requestId: ULong, + val clientNodeId: ULong, + val statusCode: UInt, + val fabricIndex: UInt, +) { + override fun toString(): String = buildString { + append("CommissionerControlClusterCommissioningRequestResultEvent {\n") + append("\trequestId : $requestId\n") + append("\tclientNodeId : $clientNodeId\n") + append("\tstatusCode : $statusCode\n") + append("\tfabricIndex : $fabricIndex\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_REQUEST_ID), requestId) + put(ContextSpecificTag(TAG_CLIENT_NODE_ID), clientNodeId) + put(ContextSpecificTag(TAG_STATUS_CODE), statusCode) + put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) + endStructure() + } + } + + companion object { + private const val TAG_REQUEST_ID = 0 + private const val TAG_CLIENT_NODE_ID = 1 + private const val TAG_STATUS_CODE = 2 + private const val TAG_FABRIC_INDEX = 254 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): CommissionerControlClusterCommissioningRequestResultEvent { + tlvReader.enterStructure(tlvTag) + val requestId = tlvReader.getULong(ContextSpecificTag(TAG_REQUEST_ID)) + val clientNodeId = tlvReader.getULong(ContextSpecificTag(TAG_CLIENT_NODE_ID)) + val statusCode = tlvReader.getUInt(ContextSpecificTag(TAG_STATUS_CODE)) + val fabricIndex = tlvReader.getUInt(ContextSpecificTag(TAG_FABRIC_INDEX)) + + tlvReader.exitContainer() + + return CommissionerControlClusterCommissioningRequestResultEvent( + requestId, + clientNodeId, + statusCode, + fabricIndex, + ) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStartedEvent.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStartedEvent.kt index 1ab0f94916c9c9..345a0aef9f870e 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStartedEvent.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStartedEvent.kt @@ -17,6 +17,7 @@ package chip.devicecontroller.cluster.eventstructs import chip.devicecontroller.cluster.* +import java.util.Optional import matter.tlv.ContextSpecificTag import matter.tlv.Tag import matter.tlv.TlvReader @@ -26,12 +27,14 @@ class EnergyEvseClusterEnergyTransferStartedEvent( val sessionID: ULong, val state: UInt, val maximumCurrent: Long, + val maximumDischargeCurrent: Optional, ) { override fun toString(): String = buildString { append("EnergyEvseClusterEnergyTransferStartedEvent {\n") append("\tsessionID : $sessionID\n") append("\tstate : $state\n") append("\tmaximumCurrent : $maximumCurrent\n") + append("\tmaximumDischargeCurrent : $maximumDischargeCurrent\n") append("}\n") } @@ -41,6 +44,10 @@ class EnergyEvseClusterEnergyTransferStartedEvent( put(ContextSpecificTag(TAG_SESSION_I_D), sessionID) put(ContextSpecificTag(TAG_STATE), state) put(ContextSpecificTag(TAG_MAXIMUM_CURRENT), maximumCurrent) + if (maximumDischargeCurrent.isPresent) { + val optmaximumDischargeCurrent = maximumDischargeCurrent.get() + put(ContextSpecificTag(TAG_MAXIMUM_DISCHARGE_CURRENT), optmaximumDischargeCurrent) + } endStructure() } } @@ -49,16 +56,28 @@ class EnergyEvseClusterEnergyTransferStartedEvent( private const val TAG_SESSION_I_D = 0 private const val TAG_STATE = 1 private const val TAG_MAXIMUM_CURRENT = 2 + private const val TAG_MAXIMUM_DISCHARGE_CURRENT = 3 fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): EnergyEvseClusterEnergyTransferStartedEvent { tlvReader.enterStructure(tlvTag) val sessionID = tlvReader.getULong(ContextSpecificTag(TAG_SESSION_I_D)) val state = tlvReader.getUInt(ContextSpecificTag(TAG_STATE)) val maximumCurrent = tlvReader.getLong(ContextSpecificTag(TAG_MAXIMUM_CURRENT)) + val maximumDischargeCurrent = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_MAXIMUM_DISCHARGE_CURRENT))) { + Optional.of(tlvReader.getLong(ContextSpecificTag(TAG_MAXIMUM_DISCHARGE_CURRENT))) + } else { + Optional.empty() + } tlvReader.exitContainer() - return EnergyEvseClusterEnergyTransferStartedEvent(sessionID, state, maximumCurrent) + return EnergyEvseClusterEnergyTransferStartedEvent( + sessionID, + state, + maximumCurrent, + maximumDischargeCurrent, + ) } } } diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStoppedEvent.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStoppedEvent.kt index 405ec933dc91e0..b6c3f8cc88f71b 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStoppedEvent.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStoppedEvent.kt @@ -17,6 +17,7 @@ package chip.devicecontroller.cluster.eventstructs import chip.devicecontroller.cluster.* +import java.util.Optional import matter.tlv.ContextSpecificTag import matter.tlv.Tag import matter.tlv.TlvReader @@ -27,6 +28,7 @@ class EnergyEvseClusterEnergyTransferStoppedEvent( val state: UInt, val reason: UInt, val energyTransferred: Long, + val energyDischarged: Optional, ) { override fun toString(): String = buildString { append("EnergyEvseClusterEnergyTransferStoppedEvent {\n") @@ -34,6 +36,7 @@ class EnergyEvseClusterEnergyTransferStoppedEvent( append("\tstate : $state\n") append("\treason : $reason\n") append("\tenergyTransferred : $energyTransferred\n") + append("\tenergyDischarged : $energyDischarged\n") append("}\n") } @@ -44,6 +47,10 @@ class EnergyEvseClusterEnergyTransferStoppedEvent( put(ContextSpecificTag(TAG_STATE), state) put(ContextSpecificTag(TAG_REASON), reason) put(ContextSpecificTag(TAG_ENERGY_TRANSFERRED), energyTransferred) + if (energyDischarged.isPresent) { + val optenergyDischarged = energyDischarged.get() + put(ContextSpecificTag(TAG_ENERGY_DISCHARGED), optenergyDischarged) + } endStructure() } } @@ -53,6 +60,7 @@ class EnergyEvseClusterEnergyTransferStoppedEvent( private const val TAG_STATE = 1 private const val TAG_REASON = 2 private const val TAG_ENERGY_TRANSFERRED = 4 + private const val TAG_ENERGY_DISCHARGED = 5 fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): EnergyEvseClusterEnergyTransferStoppedEvent { tlvReader.enterStructure(tlvTag) @@ -60,6 +68,12 @@ class EnergyEvseClusterEnergyTransferStoppedEvent( val state = tlvReader.getUInt(ContextSpecificTag(TAG_STATE)) val reason = tlvReader.getUInt(ContextSpecificTag(TAG_REASON)) val energyTransferred = tlvReader.getLong(ContextSpecificTag(TAG_ENERGY_TRANSFERRED)) + val energyDischarged = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_ENERGY_DISCHARGED))) { + Optional.of(tlvReader.getLong(ContextSpecificTag(TAG_ENERGY_DISCHARGED))) + } else { + Optional.empty() + } tlvReader.exitContainer() @@ -68,6 +82,7 @@ class EnergyEvseClusterEnergyTransferStoppedEvent( state, reason, energyTransferred, + energyDischarged, ) } } diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni index a62e5ec79a241e..631feb9442d4c0 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni @@ -163,6 +163,7 @@ eventstructs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/BooleanStateConfigurationClusterSensorFaultEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/BridgedDeviceBasicInformationClusterReachableChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/BridgedDeviceBasicInformationClusterStartUpEvent.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/DemandResponseLoadControlClusterLoadControlEventStatusChangeEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/DeviceEnergyManagementClusterPowerAdjustEndEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/DeviceEnergyManagementClusterResumedEvent.kt", diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/CommissionerControlCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/CommissionerControlCluster.kt new file mode 100644 index 00000000000000..6a3d288d56e49c --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/CommissionerControlCluster.kt @@ -0,0 +1,874 @@ +/* + * + * Copyright (c) 2023 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. + */ + +package matter.controller.cluster.clusters + +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.transform +import matter.controller.InvokeRequest +import matter.controller.InvokeResponse +import matter.controller.MatterController +import matter.controller.ReadData +import matter.controller.ReadRequest +import matter.controller.SubscribeRequest +import matter.controller.SubscriptionState +import matter.controller.UIntSubscriptionState +import matter.controller.UShortSubscriptionState +import matter.controller.cluster.structs.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class CommissionerControlCluster( + private val controller: MatterController, + private val endpointId: UShort, +) { + class ReverseOpenCommissioningWindow( + val commissioningTimeout: UShort, + val PAKEPasscodeVerifier: ByteArray, + val discriminator: UShort, + val iterations: UInt, + val salt: ByteArray, + ) + + class GeneratedCommandListAttribute(val value: List) + + sealed class GeneratedCommandListAttributeSubscriptionState { + data class Success(val value: List) : GeneratedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : GeneratedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : GeneratedCommandListAttributeSubscriptionState() + } + + class AcceptedCommandListAttribute(val value: List) + + sealed class AcceptedCommandListAttributeSubscriptionState { + data class Success(val value: List) : AcceptedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AcceptedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : AcceptedCommandListAttributeSubscriptionState() + } + + class EventListAttribute(val value: List) + + sealed class EventListAttributeSubscriptionState { + data class Success(val value: List) : EventListAttributeSubscriptionState() + + data class Error(val exception: Exception) : EventListAttributeSubscriptionState() + + object SubscriptionEstablished : EventListAttributeSubscriptionState() + } + + class AttributeListAttribute(val value: List) + + sealed class AttributeListAttributeSubscriptionState { + data class Success(val value: List) : AttributeListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AttributeListAttributeSubscriptionState() + + object SubscriptionEstablished : AttributeListAttributeSubscriptionState() + } + + suspend fun requestCommissioningApproval( + requestId: ULong, + vendorId: UShort, + productId: UShort, + label: String?, + timedInvokeTimeout: Duration? = null, + ) { + val commandId: UInt = 0u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_REQUEST_ID_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_REQUEST_ID_REQ), requestId) + + val TAG_VENDOR_ID_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_VENDOR_ID_REQ), vendorId) + + val TAG_PRODUCT_ID_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_PRODUCT_ID_REQ), productId) + + val TAG_LABEL_REQ: Int = 3 + label?.let { tlvWriter.put(ContextSpecificTag(TAG_LABEL_REQ), label) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout, + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + } + + suspend fun commissionNode( + requestId: ULong, + responseTimeoutSeconds: UShort, + ipAddress: ByteArray?, + port: UShort?, + timedInvokeTimeout: Duration? = null, + ): ReverseOpenCommissioningWindow { + val commandId: UInt = 1u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_REQUEST_ID_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_REQUEST_ID_REQ), requestId) + + val TAG_RESPONSE_TIMEOUT_SECONDS_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_RESPONSE_TIMEOUT_SECONDS_REQ), responseTimeoutSeconds) + + val TAG_IP_ADDRESS_REQ: Int = 2 + ipAddress?.let { tlvWriter.put(ContextSpecificTag(TAG_IP_ADDRESS_REQ), ipAddress) } + + val TAG_PORT_REQ: Int = 3 + port?.let { tlvWriter.put(ContextSpecificTag(TAG_PORT_REQ), port) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout, + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_COMMISSIONING_TIMEOUT: Int = 0 + var commissioningTimeout_decoded: UShort? = null + + val TAG_P_A_K_E_PASSCODE_VERIFIER: Int = 1 + var PAKEPasscodeVerifier_decoded: ByteArray? = null + + val TAG_DISCRIMINATOR: Int = 2 + var discriminator_decoded: UShort? = null + + val TAG_ITERATIONS: Int = 3 + var iterations_decoded: UInt? = null + + val TAG_SALT: Int = 4 + var salt_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_COMMISSIONING_TIMEOUT)) { + commissioningTimeout_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_P_A_K_E_PASSCODE_VERIFIER)) { + PAKEPasscodeVerifier_decoded = tlvReader.getByteArray(tag) + } + + if (tag == ContextSpecificTag(TAG_DISCRIMINATOR)) { + discriminator_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_ITERATIONS)) { + iterations_decoded = tlvReader.getUInt(tag) + } + + if (tag == ContextSpecificTag(TAG_SALT)) { + salt_decoded = tlvReader.getByteArray(tag) + } else { + tlvReader.skipElement() + } + } + + if (commissioningTimeout_decoded == null) { + throw IllegalStateException("commissioningTimeout not found in TLV") + } + + if (PAKEPasscodeVerifier_decoded == null) { + throw IllegalStateException("PAKEPasscodeVerifier not found in TLV") + } + + if (discriminator_decoded == null) { + throw IllegalStateException("discriminator not found in TLV") + } + + if (iterations_decoded == null) { + throw IllegalStateException("iterations not found in TLV") + } + + if (salt_decoded == null) { + throw IllegalStateException("salt not found in TLV") + } + + tlvReader.exitContainer() + + return ReverseOpenCommissioningWindow( + commissioningTimeout_decoded, + PAKEPasscodeVerifier_decoded, + discriminator_decoded, + iterations_decoded, + salt_decoded, + ) + } + + suspend fun readSupportedDeviceCategoriesAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supporteddevicecategories attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeSupportedDeviceCategoriesAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 0u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UIntSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Supporteddevicecategories attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + emit(UIntSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UIntSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) + } + + suspend fun subscribeGeneratedCommandListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65528u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + GeneratedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Generatedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(GeneratedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(GeneratedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) + } + + suspend fun subscribeAcceptedCommandListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65529u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AcceptedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Acceptedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AcceptedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AcceptedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readEventListAttribute(): EventListAttribute { + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) + } + + suspend fun subscribeEventListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65530u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + EventListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Eventlist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(EventListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(EventListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAttributeListAttribute(): AttributeListAttribute { + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) + } + + suspend fun subscribeAttributeListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65531u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AttributeListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Attributelist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AttributeListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AttributeListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readFeatureMapAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeFeatureMapAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65532u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UIntSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Featuremap attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + emit(UIntSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UIntSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readClusterRevisionAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeClusterRevisionAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65533u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UShortSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Clusterrevision attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + emit(UShortSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UShortSubscriptionState.SubscriptionEstablished) + } + } + } + } + + companion object { + private val logger = Logger.getLogger(CommissionerControlCluster::class.java.name) + const val CLUSTER_ID: UInt = 1873u + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadBorderRouterManagementCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadBorderRouterManagementCluster.kt index 74a006c4d2a96b..b212ff7904d2fc 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadBorderRouterManagementCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadBorderRouterManagementCluster.kt @@ -185,7 +185,7 @@ class ThreadBorderRouterManagementCluster( breadcrumb: ULong?, timedInvokeTimeout: Duration? = null, ) { - val commandId: UInt = 4u + val commandId: UInt = 3u val tlvWriter = TlvWriter() tlvWriter.startStructure(AnonymousTag) @@ -212,7 +212,7 @@ class ThreadBorderRouterManagementCluster( pendingDataset: ByteArray, timedInvokeTimeout: Duration? = null, ) { - val commandId: UInt = 5u + val commandId: UInt = 4u val tlvWriter = TlvWriter() tlvWriter.startStructure(AnonymousTag) @@ -561,7 +561,7 @@ class ThreadBorderRouterManagementCluster( } suspend fun readActiveDatasetTimestampAttribute(): ActiveDatasetTimestampAttribute { - val ATTRIBUTE_ID: UInt = 5u + val ATTRIBUTE_ID: UInt = 4u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -601,7 +601,7 @@ class ThreadBorderRouterManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 5u + val ATTRIBUTE_ID: UInt = 4u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterManagementCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterManagementCluster.kt new file mode 100644 index 00000000000000..7d0ce89e2a612e --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterManagementCluster.kt @@ -0,0 +1,1228 @@ +/* + * + * Copyright (c) 2023 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. + */ + +package matter.controller.cluster.clusters + +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.transform +import matter.controller.InvokeRequest +import matter.controller.InvokeResponse +import matter.controller.LongSubscriptionState +import matter.controller.MatterController +import matter.controller.ReadData +import matter.controller.ReadRequest +import matter.controller.SubscribeRequest +import matter.controller.SubscriptionState +import matter.controller.UByteSubscriptionState +import matter.controller.UIntSubscriptionState +import matter.controller.UShortSubscriptionState +import matter.controller.cluster.structs.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WaterHeaterManagementCluster( + private val controller: MatterController, + private val endpointId: UShort, +) { + class GeneratedCommandListAttribute(val value: List) + + sealed class GeneratedCommandListAttributeSubscriptionState { + data class Success(val value: List) : GeneratedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : GeneratedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : GeneratedCommandListAttributeSubscriptionState() + } + + class AcceptedCommandListAttribute(val value: List) + + sealed class AcceptedCommandListAttributeSubscriptionState { + data class Success(val value: List) : AcceptedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AcceptedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : AcceptedCommandListAttributeSubscriptionState() + } + + class EventListAttribute(val value: List) + + sealed class EventListAttributeSubscriptionState { + data class Success(val value: List) : EventListAttributeSubscriptionState() + + data class Error(val exception: Exception) : EventListAttributeSubscriptionState() + + object SubscriptionEstablished : EventListAttributeSubscriptionState() + } + + class AttributeListAttribute(val value: List) + + sealed class AttributeListAttributeSubscriptionState { + data class Success(val value: List) : AttributeListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AttributeListAttributeSubscriptionState() + + object SubscriptionEstablished : AttributeListAttributeSubscriptionState() + } + + suspend fun boost( + duration: UInt, + oneShot: Boolean?, + emergencyBoost: Boolean?, + temporarySetpoint: Short?, + targetPercentage: UByte?, + targetReheat: UByte?, + timedInvokeTimeout: Duration? = null, + ) { + val commandId: UInt = 0u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_DURATION_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_DURATION_REQ), duration) + + val TAG_ONE_SHOT_REQ: Int = 1 + oneShot?.let { tlvWriter.put(ContextSpecificTag(TAG_ONE_SHOT_REQ), oneShot) } + + val TAG_EMERGENCY_BOOST_REQ: Int = 2 + emergencyBoost?.let { + tlvWriter.put(ContextSpecificTag(TAG_EMERGENCY_BOOST_REQ), emergencyBoost) + } + + val TAG_TEMPORARY_SETPOINT_REQ: Int = 3 + temporarySetpoint?.let { + tlvWriter.put(ContextSpecificTag(TAG_TEMPORARY_SETPOINT_REQ), temporarySetpoint) + } + + val TAG_TARGET_PERCENTAGE_REQ: Int = 4 + targetPercentage?.let { + tlvWriter.put(ContextSpecificTag(TAG_TARGET_PERCENTAGE_REQ), targetPercentage) + } + + val TAG_TARGET_REHEAT_REQ: Int = 5 + targetReheat?.let { tlvWriter.put(ContextSpecificTag(TAG_TARGET_REHEAT_REQ), targetReheat) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout, + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + } + + suspend fun cancelBoost(timedInvokeTimeout: Duration? = null) { + val commandId: UInt = 1u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout, + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + } + + suspend fun readHeaterTypesAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Heatertypes attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeHeaterTypesAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 0u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UByteSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Heatertypes attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + emit(UByteSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UByteSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readHeatDemandAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Heatdemand attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeHeatDemandAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 1u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UByteSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Heatdemand attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + emit(UByteSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UByteSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readTankVolumeAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Tankvolume attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun subscribeTankVolumeAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 2u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UShortSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Tankvolume attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + decodedValue?.let { emit(UShortSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(UShortSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readEstimatedHeatRequiredAttribute(): Long? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Estimatedheatrequired attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getLong(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun subscribeEstimatedHeatRequiredAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 3u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + LongSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Estimatedheatrequired attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getLong(AnonymousTag) + } else { + null + } + + decodedValue?.let { emit(LongSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(LongSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readTankPercentageAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Tankpercentage attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun subscribeTankPercentageAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 4u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UByteSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Tankpercentage attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + decodedValue?.let { emit(UByteSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(UByteSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readBoostStateAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Booststate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeBoostStateAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 5u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UByteSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Booststate attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + emit(UByteSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UByteSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) + } + + suspend fun subscribeGeneratedCommandListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65528u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + GeneratedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Generatedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(GeneratedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(GeneratedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) + } + + suspend fun subscribeAcceptedCommandListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65529u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AcceptedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Acceptedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AcceptedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AcceptedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readEventListAttribute(): EventListAttribute { + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) + } + + suspend fun subscribeEventListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65530u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + EventListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Eventlist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(EventListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(EventListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAttributeListAttribute(): AttributeListAttribute { + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) + } + + suspend fun subscribeAttributeListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65531u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AttributeListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Attributelist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AttributeListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AttributeListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readFeatureMapAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeFeatureMapAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65532u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UIntSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Featuremap attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + emit(UIntSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UIntSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readClusterRevisionAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeClusterRevisionAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65533u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UShortSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Clusterrevision attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + emit(UShortSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UShortSubscriptionState.SubscriptionEstablished) + } + } + } + } + + companion object { + private val logger = Logger.getLogger(WaterHeaterManagementCluster::class.java.name) + const val CLUSTER_ID: UInt = 148u + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt new file mode 100644 index 00000000000000..c8947776269773 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt @@ -0,0 +1,77 @@ +/* + * + * Copyright (c) 2023 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. + */ +package matter.controller.cluster.eventstructs + +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class CommissionerControlClusterCommissioningRequestResultEvent( + val requestId: ULong, + val clientNodeId: ULong, + val statusCode: UByte, + val fabricIndex: UByte, +) { + override fun toString(): String = buildString { + append("CommissionerControlClusterCommissioningRequestResultEvent {\n") + append("\trequestId : $requestId\n") + append("\tclientNodeId : $clientNodeId\n") + append("\tstatusCode : $statusCode\n") + append("\tfabricIndex : $fabricIndex\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_REQUEST_ID), requestId) + put(ContextSpecificTag(TAG_CLIENT_NODE_ID), clientNodeId) + put(ContextSpecificTag(TAG_STATUS_CODE), statusCode) + put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) + endStructure() + } + } + + companion object { + private const val TAG_REQUEST_ID = 0 + private const val TAG_CLIENT_NODE_ID = 1 + private const val TAG_STATUS_CODE = 2 + private const val TAG_FABRIC_INDEX = 254 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): CommissionerControlClusterCommissioningRequestResultEvent { + tlvReader.enterStructure(tlvTag) + val requestId = tlvReader.getULong(ContextSpecificTag(TAG_REQUEST_ID)) + val clientNodeId = tlvReader.getULong(ContextSpecificTag(TAG_CLIENT_NODE_ID)) + val statusCode = tlvReader.getUByte(ContextSpecificTag(TAG_STATUS_CODE)) + val fabricIndex = tlvReader.getUByte(ContextSpecificTag(TAG_FABRIC_INDEX)) + + tlvReader.exitContainer() + + return CommissionerControlClusterCommissioningRequestResultEvent( + requestId, + clientNodeId, + statusCode, + fabricIndex, + ) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStartedEvent.kt b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStartedEvent.kt index 28c49717661652..17459394a0bfef 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStartedEvent.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStartedEvent.kt @@ -16,6 +16,7 @@ */ package matter.controller.cluster.eventstructs +import java.util.Optional import matter.controller.cluster.* import matter.tlv.ContextSpecificTag import matter.tlv.Tag @@ -26,12 +27,14 @@ class EnergyEvseClusterEnergyTransferStartedEvent( val sessionID: UInt, val state: UByte, val maximumCurrent: Long, + val maximumDischargeCurrent: Optional, ) { override fun toString(): String = buildString { append("EnergyEvseClusterEnergyTransferStartedEvent {\n") append("\tsessionID : $sessionID\n") append("\tstate : $state\n") append("\tmaximumCurrent : $maximumCurrent\n") + append("\tmaximumDischargeCurrent : $maximumDischargeCurrent\n") append("}\n") } @@ -41,6 +44,10 @@ class EnergyEvseClusterEnergyTransferStartedEvent( put(ContextSpecificTag(TAG_SESSION_I_D), sessionID) put(ContextSpecificTag(TAG_STATE), state) put(ContextSpecificTag(TAG_MAXIMUM_CURRENT), maximumCurrent) + if (maximumDischargeCurrent.isPresent) { + val optmaximumDischargeCurrent = maximumDischargeCurrent.get() + put(ContextSpecificTag(TAG_MAXIMUM_DISCHARGE_CURRENT), optmaximumDischargeCurrent) + } endStructure() } } @@ -49,16 +56,28 @@ class EnergyEvseClusterEnergyTransferStartedEvent( private const val TAG_SESSION_I_D = 0 private const val TAG_STATE = 1 private const val TAG_MAXIMUM_CURRENT = 2 + private const val TAG_MAXIMUM_DISCHARGE_CURRENT = 3 fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): EnergyEvseClusterEnergyTransferStartedEvent { tlvReader.enterStructure(tlvTag) val sessionID = tlvReader.getUInt(ContextSpecificTag(TAG_SESSION_I_D)) val state = tlvReader.getUByte(ContextSpecificTag(TAG_STATE)) val maximumCurrent = tlvReader.getLong(ContextSpecificTag(TAG_MAXIMUM_CURRENT)) + val maximumDischargeCurrent = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_MAXIMUM_DISCHARGE_CURRENT))) { + Optional.of(tlvReader.getLong(ContextSpecificTag(TAG_MAXIMUM_DISCHARGE_CURRENT))) + } else { + Optional.empty() + } tlvReader.exitContainer() - return EnergyEvseClusterEnergyTransferStartedEvent(sessionID, state, maximumCurrent) + return EnergyEvseClusterEnergyTransferStartedEvent( + sessionID, + state, + maximumCurrent, + maximumDischargeCurrent, + ) } } } diff --git a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStoppedEvent.kt b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStoppedEvent.kt index e044a582d7f500..56c91b5c1beb71 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStoppedEvent.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStoppedEvent.kt @@ -16,6 +16,7 @@ */ package matter.controller.cluster.eventstructs +import java.util.Optional import matter.controller.cluster.* import matter.tlv.ContextSpecificTag import matter.tlv.Tag @@ -27,6 +28,7 @@ class EnergyEvseClusterEnergyTransferStoppedEvent( val state: UByte, val reason: UByte, val energyTransferred: Long, + val energyDischarged: Optional, ) { override fun toString(): String = buildString { append("EnergyEvseClusterEnergyTransferStoppedEvent {\n") @@ -34,6 +36,7 @@ class EnergyEvseClusterEnergyTransferStoppedEvent( append("\tstate : $state\n") append("\treason : $reason\n") append("\tenergyTransferred : $energyTransferred\n") + append("\tenergyDischarged : $energyDischarged\n") append("}\n") } @@ -44,6 +47,10 @@ class EnergyEvseClusterEnergyTransferStoppedEvent( put(ContextSpecificTag(TAG_STATE), state) put(ContextSpecificTag(TAG_REASON), reason) put(ContextSpecificTag(TAG_ENERGY_TRANSFERRED), energyTransferred) + if (energyDischarged.isPresent) { + val optenergyDischarged = energyDischarged.get() + put(ContextSpecificTag(TAG_ENERGY_DISCHARGED), optenergyDischarged) + } endStructure() } } @@ -53,6 +60,7 @@ class EnergyEvseClusterEnergyTransferStoppedEvent( private const val TAG_STATE = 1 private const val TAG_REASON = 2 private const val TAG_ENERGY_TRANSFERRED = 4 + private const val TAG_ENERGY_DISCHARGED = 5 fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): EnergyEvseClusterEnergyTransferStoppedEvent { tlvReader.enterStructure(tlvTag) @@ -60,6 +68,12 @@ class EnergyEvseClusterEnergyTransferStoppedEvent( val state = tlvReader.getUByte(ContextSpecificTag(TAG_STATE)) val reason = tlvReader.getUByte(ContextSpecificTag(TAG_REASON)) val energyTransferred = tlvReader.getLong(ContextSpecificTag(TAG_ENERGY_TRANSFERRED)) + val energyDischarged = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_ENERGY_DISCHARGED))) { + Optional.of(tlvReader.getLong(ContextSpecificTag(TAG_ENERGY_DISCHARGED))) + } else { + Optional.empty() + } tlvReader.exitContainer() @@ -68,6 +82,7 @@ class EnergyEvseClusterEnergyTransferStoppedEvent( state, reason, energyTransferred, + energyDischarged, ) } } diff --git a/src/controller/java/generated/java/matter/controller/cluster/files.gni b/src/controller/java/generated/java/matter/controller/cluster/files.gni index 27e731d29bf4d9..2bebadb13c36ce 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/files.gni +++ b/src/controller/java/generated/java/matter/controller/cluster/files.gni @@ -163,6 +163,7 @@ matter_eventstructs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/BooleanStateConfigurationClusterSensorFaultEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/BridgedDeviceBasicInformationClusterReachableChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/BridgedDeviceBasicInformationClusterStartUpEvent.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/DemandResponseLoadControlClusterLoadControlEventStatusChangeEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/DeviceEnergyManagementClusterPowerAdjustEndEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/DeviceEnergyManagementClusterResumedEvent.kt", @@ -254,6 +255,7 @@ matter_clusters_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/CarbonMonoxideConcentrationMeasurementCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ChannelCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ColorControlCluster.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/CommissionerControlCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ContentAppObserverCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ContentControlCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ContentLauncherCluster.kt", @@ -352,6 +354,7 @@ matter_clusters_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/UserLabelCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ValveConfigurationAndControlCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WakeOnLanCluster.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterManagementCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WiFiNetworkDiagnosticsCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WiFiNetworkManagementCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WindowCoveringCluster.kt", diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index 66797f78118dd1..01a75bcc216288 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -21605,6 +21605,244 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } + case app::Clusters::WaterHeaterManagement::Id: { + using namespace app::Clusters::WaterHeaterManagement; + switch (aPath.mAttributeId) + { + case Attributes::HeaterTypes::Id: { + using TypeInfo = Attributes::HeaterTypes::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Raw()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::HeatDemand::Id: { + using TypeInfo = Attributes::HeatDemand::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Raw()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::TankVolume::Id: { + using TypeInfo = Attributes::TankVolume::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::EstimatedHeatRequired::Id: { + using TypeInfo = Attributes::EstimatedHeatRequired::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::TankPercentage::Id: { + using TypeInfo = Attributes::TankPercentage::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::BoostState::Id: { + using TypeInfo = Attributes::BoostState::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::EventList::Id: { + using TypeInfo = Attributes::EventList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AttributeList::Id: { + using TypeInfo = Attributes::AttributeList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::FeatureMap::Id: { + using TypeInfo = Attributes::FeatureMap::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::ClusterRevision::Id: { + using TypeInfo = Attributes::ClusterRevision::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + break; + } + break; + } case app::Clusters::DemandResponseLoadControl::Id: { using namespace app::Clusters::DemandResponseLoadControl; switch (aPath.mAttributeId) @@ -42162,6 +42400,164 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } + case app::Clusters::CommissionerControl::Id: { + using namespace app::Clusters::CommissionerControl; + switch (aPath.mAttributeId) + { + case Attributes::SupportedDeviceCategories::Id: { + using TypeInfo = Attributes::SupportedDeviceCategories::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue.Raw()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::EventList::Id: { + using TypeInfo = Attributes::EventList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AttributeList::Id: { + using TypeInfo = Attributes::AttributeList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::FeatureMap::Id: { + using TypeInfo = Attributes::FeatureMap::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::ClusterRevision::Id: { + using TypeInfo = Attributes::ClusterRevision::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + break; + } + break; + } case app::Clusters::ElectricalMeasurement::Id: { using namespace app::Clusters::ElectricalMeasurement; switch (aPath.mAttributeId) diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp index 4db00a7efd0f57..a61c38ca0edcc6 100644 --- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp @@ -4896,6 +4896,16 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } break; } + case app::Clusters::WaterHeaterManagement::Id: { + using namespace app::Clusters::WaterHeaterManagement; + switch (aPath.mEventId) + { + default: + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + break; + } + break; + } case app::Clusters::DemandResponseLoadControl::Id: { using namespace app::Clusters::DemandResponseLoadControl; switch (aPath.mEventId) @@ -5862,6 +5872,25 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & value_maximumCurrentCtorSignature.c_str(), jnivalue_maximumCurrent, value_maximumCurrent); + jobject value_maximumDischargeCurrent; + if (!cppValue.maximumDischargeCurrent.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, value_maximumDischargeCurrent); + } + else + { + jobject value_maximumDischargeCurrentInsideOptional; + std::string value_maximumDischargeCurrentInsideOptionalClassName = "java/lang/Long"; + std::string value_maximumDischargeCurrentInsideOptionalCtorSignature = "(J)V"; + jlong jnivalue_maximumDischargeCurrentInsideOptional = static_cast(cppValue.maximumDischargeCurrent.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_maximumDischargeCurrentInsideOptionalClassName.c_str(), + value_maximumDischargeCurrentInsideOptionalCtorSignature.c_str(), + jnivalue_maximumDischargeCurrentInsideOptional, value_maximumDischargeCurrentInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(value_maximumDischargeCurrentInsideOptional, + value_maximumDischargeCurrent); + } + jclass energyTransferStartedStructClass; err = chip::JniReferences::GetInstance().GetLocalClassRef( env, "chip/devicecontroller/ChipEventStructs$EnergyEvseClusterEnergyTransferStartedEvent", @@ -5873,9 +5902,9 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } jmethodID energyTransferStartedStructCtor; - err = chip::JniReferences::GetInstance().FindMethod(env, energyTransferStartedStructClass, "", - "(Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Long;)V", - &energyTransferStartedStructCtor); + err = chip::JniReferences::GetInstance().FindMethod( + env, energyTransferStartedStructClass, "", + "(Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Long;Ljava/util/Optional;)V", &energyTransferStartedStructCtor); if (err != CHIP_NO_ERROR || energyTransferStartedStructCtor == nullptr) { ChipLogError(Zcl, "Could not find ChipEventStructs$EnergyEvseClusterEnergyTransferStartedEvent constructor"); @@ -5883,7 +5912,7 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } jobject value = env->NewObject(energyTransferStartedStructClass, energyTransferStartedStructCtor, value_sessionID, - value_state, value_maximumCurrent); + value_state, value_maximumCurrent, value_maximumDischargeCurrent); return value; } @@ -5923,6 +5952,24 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & value_energyTransferredCtorSignature.c_str(), jnivalue_energyTransferred, value_energyTransferred); + jobject value_energyDischarged; + if (!cppValue.energyDischarged.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, value_energyDischarged); + } + else + { + jobject value_energyDischargedInsideOptional; + std::string value_energyDischargedInsideOptionalClassName = "java/lang/Long"; + std::string value_energyDischargedInsideOptionalCtorSignature = "(J)V"; + jlong jnivalue_energyDischargedInsideOptional = static_cast(cppValue.energyDischarged.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_energyDischargedInsideOptionalClassName.c_str(), + value_energyDischargedInsideOptionalCtorSignature.c_str(), jnivalue_energyDischargedInsideOptional, + value_energyDischargedInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(value_energyDischargedInsideOptional, value_energyDischarged); + } + jclass energyTransferStoppedStructClass; err = chip::JniReferences::GetInstance().GetLocalClassRef( env, "chip/devicecontroller/ChipEventStructs$EnergyEvseClusterEnergyTransferStoppedEvent", @@ -5936,7 +5983,8 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & jmethodID energyTransferStoppedStructCtor; err = chip::JniReferences::GetInstance().FindMethod( env, energyTransferStoppedStructClass, "", - "(Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Long;)V", &energyTransferStoppedStructCtor); + "(Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Long;Ljava/util/Optional;)V", + &energyTransferStoppedStructCtor); if (err != CHIP_NO_ERROR || energyTransferStoppedStructCtor == nullptr) { ChipLogError(Zcl, "Could not find ChipEventStructs$EnergyEvseClusterEnergyTransferStoppedEvent constructor"); @@ -5944,7 +5992,7 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } jobject value = env->NewObject(energyTransferStoppedStructClass, energyTransferStoppedStructCtor, value_sessionID, - value_state, value_reason, value_energyTransferred); + value_state, value_reason, value_energyTransferred, value_energyDischarged); return value; } @@ -7920,6 +7968,80 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } break; } + case app::Clusters::CommissionerControl::Id: { + using namespace app::Clusters::CommissionerControl; + switch (aPath.mEventId) + { + case Events::CommissioningRequestResult::Id: { + Events::CommissioningRequestResult::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value_requestId; + std::string value_requestIdClassName = "java/lang/Long"; + std::string value_requestIdCtorSignature = "(J)V"; + jlong jnivalue_requestId = static_cast(cppValue.requestId); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_requestIdClassName.c_str(), value_requestIdCtorSignature.c_str(), jnivalue_requestId, value_requestId); + + jobject value_clientNodeId; + std::string value_clientNodeIdClassName = "java/lang/Long"; + std::string value_clientNodeIdCtorSignature = "(J)V"; + jlong jnivalue_clientNodeId = static_cast(cppValue.clientNodeId); + chip::JniReferences::GetInstance().CreateBoxedObject(value_clientNodeIdClassName.c_str(), + value_clientNodeIdCtorSignature.c_str(), + jnivalue_clientNodeId, value_clientNodeId); + + jobject value_statusCode; + std::string value_statusCodeClassName = "java/lang/Integer"; + std::string value_statusCodeCtorSignature = "(I)V"; + jint jnivalue_statusCode = static_cast(cppValue.statusCode); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_statusCodeClassName.c_str(), value_statusCodeCtorSignature.c_str(), jnivalue_statusCode, value_statusCode); + + jobject value_fabricIndex; + std::string value_fabricIndexClassName = "java/lang/Integer"; + std::string value_fabricIndexCtorSignature = "(I)V"; + jint jnivalue_fabricIndex = static_cast(cppValue.fabricIndex); + chip::JniReferences::GetInstance().CreateBoxedObject(value_fabricIndexClassName.c_str(), + value_fabricIndexCtorSignature.c_str(), jnivalue_fabricIndex, + value_fabricIndex); + + jclass commissioningRequestResultStructClass; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipEventStructs$CommissionerControlClusterCommissioningRequestResultEvent", + commissioningRequestResultStructClass); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, + "Could not find class ChipEventStructs$CommissionerControlClusterCommissioningRequestResultEvent"); + return nullptr; + } + + jmethodID commissioningRequestResultStructCtor; + err = chip::JniReferences::GetInstance().FindMethod( + env, commissioningRequestResultStructClass, "", + "(Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Integer;)V", &commissioningRequestResultStructCtor); + if (err != CHIP_NO_ERROR || commissioningRequestResultStructCtor == nullptr) + { + ChipLogError( + Zcl, "Could not find ChipEventStructs$CommissionerControlClusterCommissioningRequestResultEvent constructor"); + return nullptr; + } + + jobject value = env->NewObject(commissioningRequestResultStructClass, commissioningRequestResultStructCtor, + value_requestId, value_clientNodeId, value_statusCode, value_fabricIndex); + + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + break; + } + break; + } case app::Clusters::ElectricalMeasurement::Id: { using namespace app::Clusters::ElectricalMeasurement; switch (aPath.mEventId) diff --git a/src/controller/python/ChipCommissionableNodeController-ScriptBinding.cpp b/src/controller/python/ChipCommissionableNodeController-ScriptBinding.cpp index 157789f5d64136..806bd5b5bb8be4 100644 --- a/src/controller/python/ChipCommissionableNodeController-ScriptBinding.cpp +++ b/src/controller/python/ChipCommissionableNodeController-ScriptBinding.cpp @@ -117,7 +117,9 @@ void pychip_CommissionableNodeController_PrintDiscoveredCommissioners( { ChipLogProgress(Discovery, "\tMrp Interval active\tNot present"); } - ChipLogProgress(Discovery, "\tSupports TCP\t\t%d", dnsSdInfo->supportsTcp); + + ChipLogProgress(Discovery, "\tSupports TCP Client\t\t%d", dnsSdInfo->supportsTcpClient); + ChipLogProgress(Discovery, "\tSupports TCP Server\t\t%d", dnsSdInfo->supportsTcpServer); if (dnsSdInfo->isICDOperatingAsLIT.has_value()) { diff --git a/src/controller/python/ChipDeviceController-Discovery.cpp b/src/controller/python/ChipDeviceController-Discovery.cpp index 46f0729d61243c..7c669603f4ff1d 100644 --- a/src/controller/python/ChipDeviceController-Discovery.cpp +++ b/src/controller/python/ChipDeviceController-Discovery.cpp @@ -142,7 +142,9 @@ void pychip_DeviceController_IterateDiscoveredCommissionableNodes(Controller::De { jsonVal["mrpRetryActiveThreshold"] = activeThreshold->count(); } - jsonVal["supportsTcp"] = dnsSdInfo->supportsTcp; + + jsonVal["supportsTcpClient"] = dnsSdInfo->supportsTcpClient; + jsonVal["supportsTcpServer"] = dnsSdInfo->supportsTcpServer; { Json::Value addresses; for (unsigned j = 0; j < dnsSdInfo->numIPs; ++j) diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index db05bf7319200b..5d0d1ffd38fd3c 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -6580,6 +6580,104 @@ class ChipClusters: }, }, } + _WATER_HEATER_MANAGEMENT_CLUSTER_INFO = { + "clusterName": "WaterHeaterManagement", + "clusterId": 0x00000094, + "commands": { + 0x00000000: { + "commandId": 0x00000000, + "commandName": "Boost", + "args": { + "duration": "int", + "oneShot": "bool", + "emergencyBoost": "bool", + "temporarySetpoint": "int", + "targetPercentage": "int", + "targetReheat": "int", + }, + }, + 0x00000001: { + "commandId": 0x00000001, + "commandName": "CancelBoost", + "args": { + }, + }, + }, + "attributes": { + 0x00000000: { + "attributeName": "HeaterTypes", + "attributeId": 0x00000000, + "type": "int", + "reportable": True, + }, + 0x00000001: { + "attributeName": "HeatDemand", + "attributeId": 0x00000001, + "type": "int", + "reportable": True, + }, + 0x00000002: { + "attributeName": "TankVolume", + "attributeId": 0x00000002, + "type": "int", + "reportable": True, + }, + 0x00000003: { + "attributeName": "EstimatedHeatRequired", + "attributeId": 0x00000003, + "type": "int", + "reportable": True, + }, + 0x00000004: { + "attributeName": "TankPercentage", + "attributeId": 0x00000004, + "type": "int", + "reportable": True, + }, + 0x00000005: { + "attributeName": "BoostState", + "attributeId": 0x00000005, + "type": "int", + "reportable": True, + }, + 0x0000FFF8: { + "attributeName": "GeneratedCommandList", + "attributeId": 0x0000FFF8, + "type": "int", + "reportable": True, + }, + 0x0000FFF9: { + "attributeName": "AcceptedCommandList", + "attributeId": 0x0000FFF9, + "type": "int", + "reportable": True, + }, + 0x0000FFFA: { + "attributeName": "EventList", + "attributeId": 0x0000FFFA, + "type": "int", + "reportable": True, + }, + 0x0000FFFB: { + "attributeName": "AttributeList", + "attributeId": 0x0000FFFB, + "type": "int", + "reportable": True, + }, + 0x0000FFFC: { + "attributeName": "FeatureMap", + "attributeId": 0x0000FFFC, + "type": "int", + "reportable": True, + }, + 0x0000FFFD: { + "attributeName": "ClusterRevision", + "attributeId": 0x0000FFFD, + "type": "int", + "reportable": True, + }, + }, + } _DEMAND_RESPONSE_LOAD_CONTROL_CLUSTER_INFO = { "clusterName": "DemandResponseLoadControl", "clusterId": 0x00000096, @@ -11714,16 +11812,16 @@ class ChipClusters: "args": { }, }, - 0x00000004: { - "commandId": 0x00000004, + 0x00000003: { + "commandId": 0x00000003, "commandName": "SetActiveDatasetRequest", "args": { "activeDataset": "bytes", "breadcrumb": "int", }, }, - 0x00000005: { - "commandId": 0x00000005, + 0x00000004: { + "commandId": 0x00000004, "commandName": "SetPendingDatasetRequest", "args": { "pendingDataset": "bytes", @@ -11755,9 +11853,9 @@ class ChipClusters: "type": "bool", "reportable": True, }, - 0x00000005: { + 0x00000004: { "attributeName": "ActiveDatasetTimestamp", - "attributeId": 0x00000005, + "attributeId": 0x00000004, "type": "int", "reportable": True, }, @@ -13101,6 +13199,76 @@ class ChipClusters: }, }, } + _COMMISSIONER_CONTROL_CLUSTER_INFO = { + "clusterName": "CommissionerControl", + "clusterId": 0x00000751, + "commands": { + 0x00000000: { + "commandId": 0x00000000, + "commandName": "RequestCommissioningApproval", + "args": { + "requestId": "int", + "vendorId": "int", + "productId": "int", + "label": "str", + }, + }, + 0x00000001: { + "commandId": 0x00000001, + "commandName": "CommissionNode", + "args": { + "requestId": "int", + "responseTimeoutSeconds": "int", + "ipAddress": "bytes", + "port": "int", + }, + }, + }, + "attributes": { + 0x00000000: { + "attributeName": "SupportedDeviceCategories", + "attributeId": 0x00000000, + "type": "int", + "reportable": True, + }, + 0x0000FFF8: { + "attributeName": "GeneratedCommandList", + "attributeId": 0x0000FFF8, + "type": "int", + "reportable": True, + }, + 0x0000FFF9: { + "attributeName": "AcceptedCommandList", + "attributeId": 0x0000FFF9, + "type": "int", + "reportable": True, + }, + 0x0000FFFA: { + "attributeName": "EventList", + "attributeId": 0x0000FFFA, + "type": "int", + "reportable": True, + }, + 0x0000FFFB: { + "attributeName": "AttributeList", + "attributeId": 0x0000FFFB, + "type": "int", + "reportable": True, + }, + 0x0000FFFC: { + "attributeName": "FeatureMap", + "attributeId": 0x0000FFFC, + "type": "int", + "reportable": True, + }, + 0x0000FFFD: { + "attributeName": "ClusterRevision", + "attributeId": 0x0000FFFD, + "type": "int", + "reportable": True, + }, + }, + } _ELECTRICAL_MEASUREMENT_CLUSTER_INFO = { "clusterName": "ElectricalMeasurement", "clusterId": 0x00000B04, @@ -14960,6 +15128,7 @@ class ChipClusters: 0x00000081: _VALVE_CONFIGURATION_AND_CONTROL_CLUSTER_INFO, 0x00000090: _ELECTRICAL_POWER_MEASUREMENT_CLUSTER_INFO, 0x00000091: _ELECTRICAL_ENERGY_MEASUREMENT_CLUSTER_INFO, + 0x00000094: _WATER_HEATER_MANAGEMENT_CLUSTER_INFO, 0x00000096: _DEMAND_RESPONSE_LOAD_CONTROL_CLUSTER_INFO, 0x00000097: _MESSAGES_CLUSTER_INFO, 0x00000098: _DEVICE_ENERGY_MANAGEMENT_CLUSTER_INFO, @@ -15011,6 +15180,7 @@ class ChipClusters: 0x0000050E: _ACCOUNT_LOGIN_CLUSTER_INFO, 0x0000050F: _CONTENT_CONTROL_CLUSTER_INFO, 0x00000510: _CONTENT_APP_OBSERVER_CLUSTER_INFO, + 0x00000751: _COMMISSIONER_CONTROL_CLUSTER_INFO, 0x00000B04: _ELECTRICAL_MEASUREMENT_CLUSTER_INFO, 0xFFF1FC05: _UNIT_TESTING_CLUSTER_INFO, 0xFFF1FC06: _FAULT_INJECTION_CLUSTER_INFO, @@ -15085,6 +15255,7 @@ class ChipClusters: "ValveConfigurationAndControl": _VALVE_CONFIGURATION_AND_CONTROL_CLUSTER_INFO, "ElectricalPowerMeasurement": _ELECTRICAL_POWER_MEASUREMENT_CLUSTER_INFO, "ElectricalEnergyMeasurement": _ELECTRICAL_ENERGY_MEASUREMENT_CLUSTER_INFO, + "WaterHeaterManagement": _WATER_HEATER_MANAGEMENT_CLUSTER_INFO, "DemandResponseLoadControl": _DEMAND_RESPONSE_LOAD_CONTROL_CLUSTER_INFO, "Messages": _MESSAGES_CLUSTER_INFO, "DeviceEnergyManagement": _DEVICE_ENERGY_MANAGEMENT_CLUSTER_INFO, @@ -15136,6 +15307,7 @@ class ChipClusters: "AccountLogin": _ACCOUNT_LOGIN_CLUSTER_INFO, "ContentControl": _CONTENT_CONTROL_CLUSTER_INFO, "ContentAppObserver": _CONTENT_APP_OBSERVER_CLUSTER_INFO, + "CommissionerControl": _COMMISSIONER_CONTROL_CLUSTER_INFO, "ElectricalMeasurement": _ELECTRICAL_MEASUREMENT_CLUSTER_INFO, "UnitTesting": _UNIT_TESTING_CLUSTER_INFO, "FaultInjection": _FAULT_INJECTION_CLUSTER_INFO, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 516e2f5a2e7800..a580620fdf4158 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -23204,6 +23204,304 @@ def descriptor(cls) -> ClusterObjectDescriptor: energyExported: 'typing.Optional[ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]' = None +@dataclass +class WaterHeaterManagement(Cluster): + id: typing.ClassVar[int] = 0x00000094 + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="heaterTypes", Tag=0x00000000, Type=uint), + ClusterObjectFieldDescriptor(Label="heatDemand", Tag=0x00000001, Type=uint), + ClusterObjectFieldDescriptor(Label="tankVolume", Tag=0x00000002, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="estimatedHeatRequired", Tag=0x00000003, Type=typing.Optional[int]), + ClusterObjectFieldDescriptor(Label="tankPercentage", Tag=0x00000004, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="boostState", Tag=0x00000005, Type=WaterHeaterManagement.Enums.BoostStateEnum), + ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), + ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), + ]) + + heaterTypes: 'uint' = None + heatDemand: 'uint' = None + tankVolume: 'typing.Optional[uint]' = None + estimatedHeatRequired: 'typing.Optional[int]' = None + tankPercentage: 'typing.Optional[uint]' = None + boostState: 'WaterHeaterManagement.Enums.BoostStateEnum' = None + generatedCommandList: 'typing.List[uint]' = None + acceptedCommandList: 'typing.List[uint]' = None + eventList: 'typing.List[uint]' = None + attributeList: 'typing.List[uint]' = None + featureMap: 'uint' = None + clusterRevision: 'uint' = None + + class Enums: + class BoostStateEnum(MatterIntEnum): + kInactive = 0x00 + kActive = 0x01 + # All received enum values that are not listed above will be mapped + # to kUnknownEnumValue. This is a helper enum value that should only + # be used by code to process how it handles receiving and unknown + # enum value. This specific should never be transmitted. + kUnknownEnumValue = 2, + + class Bitmaps: + class Feature(IntFlag): + kEnergyManagement = 0x1 + kTankPercent = 0x2 + + class WaterHeaterDemandBitmap(IntFlag): + kImmersionElement1 = 0x1 + kImmersionElement2 = 0x2 + kHeatPump = 0x4 + kBoiler = 0x8 + kOther = 0x10 + + class WaterHeaterTypeBitmap(IntFlag): + kImmersionElement1 = 0x1 + kImmersionElement2 = 0x2 + kHeatPump = 0x4 + kBoiler = 0x8 + kOther = 0x10 + + class Commands: + @dataclass + class Boost(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000094 + command_id: typing.ClassVar[int] = 0x00000000 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="duration", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="oneShot", Tag=1, Type=typing.Optional[bool]), + ClusterObjectFieldDescriptor(Label="emergencyBoost", Tag=2, Type=typing.Optional[bool]), + ClusterObjectFieldDescriptor(Label="temporarySetpoint", Tag=3, Type=typing.Optional[int]), + ClusterObjectFieldDescriptor(Label="targetPercentage", Tag=4, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="targetReheat", Tag=5, Type=typing.Optional[uint]), + ]) + + duration: 'uint' = 0 + oneShot: 'typing.Optional[bool]' = None + emergencyBoost: 'typing.Optional[bool]' = None + temporarySetpoint: 'typing.Optional[int]' = None + targetPercentage: 'typing.Optional[uint]' = None + targetReheat: 'typing.Optional[uint]' = None + + @dataclass + class CancelBoost(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000094 + command_id: typing.ClassVar[int] = 0x00000001 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ]) + + class Attributes: + @dataclass + class HeaterTypes(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000094 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class HeatDemand(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000094 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000001 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class TankVolume(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000094 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000002 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) + + value: 'typing.Optional[uint]' = None + + @dataclass + class EstimatedHeatRequired(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000094 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000003 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) + + value: 'typing.Optional[int]' = None + + @dataclass + class TankPercentage(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000094 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000004 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) + + value: 'typing.Optional[uint]' = None + + @dataclass + class BoostState(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000094 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000005 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=WaterHeaterManagement.Enums.BoostStateEnum) + + value: 'WaterHeaterManagement.Enums.BoostStateEnum' = 0 + + @dataclass + class GeneratedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000094 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF8 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AcceptedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000094 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF9 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class EventList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000094 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFA + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AttributeList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000094 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFB + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class FeatureMap(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000094 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFC + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class ClusterRevision(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000094 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFD + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass class DemandResponseLoadControl(Cluster): id: typing.ClassVar[int] = 0x00000096 @@ -25013,11 +25311,12 @@ class SupplyStateEnum(MatterIntEnum): kDischargingEnabled = 0x02 kDisabledError = 0x03 kDisabledDiagnostics = 0x04 + kEnabled = 0x05 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only # be used by code to process how it handles receiving and unknown # enum value. This specific should never be transmitted. - kUnknownEnumValue = 5, + kUnknownEnumValue = 6, class Bitmaps: class Feature(IntFlag): @@ -25745,11 +26044,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sessionID", Tag=0, Type=uint), ClusterObjectFieldDescriptor(Label="state", Tag=1, Type=EnergyEvse.Enums.StateEnum), ClusterObjectFieldDescriptor(Label="maximumCurrent", Tag=2, Type=int), + ClusterObjectFieldDescriptor(Label="maximumDischargeCurrent", Tag=3, Type=typing.Optional[int]), ]) sessionID: 'uint' = 0 state: 'EnergyEvse.Enums.StateEnum' = 0 maximumCurrent: 'int' = 0 + maximumDischargeCurrent: 'typing.Optional[int]' = None @dataclass class EnergyTransferStopped(ClusterEvent): @@ -25769,12 +26070,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="state", Tag=1, Type=EnergyEvse.Enums.StateEnum), ClusterObjectFieldDescriptor(Label="reason", Tag=2, Type=EnergyEvse.Enums.EnergyTransferStoppedReasonEnum), ClusterObjectFieldDescriptor(Label="energyTransferred", Tag=4, Type=int), + ClusterObjectFieldDescriptor(Label="energyDischarged", Tag=5, Type=typing.Optional[int]), ]) sessionID: 'uint' = 0 state: 'EnergyEvse.Enums.StateEnum' = 0 reason: 'EnergyEvse.Enums.EnergyTransferStoppedReasonEnum' = 0 energyTransferred: 'int' = 0 + energyDischarged: 'typing.Optional[int]' = None @dataclass class Fault(ClusterEvent): @@ -41148,7 +41451,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="borderAgentID", Tag=0x00000001, Type=bytes), ClusterObjectFieldDescriptor(Label="threadVersion", Tag=0x00000002, Type=uint), ClusterObjectFieldDescriptor(Label="interfaceEnabled", Tag=0x00000003, Type=bool), - ClusterObjectFieldDescriptor(Label="activeDatasetTimestamp", Tag=0x00000005, Type=typing.Union[Nullable, uint]), + ClusterObjectFieldDescriptor(Label="activeDatasetTimestamp", Tag=0x00000004, Type=typing.Union[Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), @@ -41203,7 +41506,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: @dataclass class DatasetResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000452 - command_id: typing.ClassVar[int] = 0x00000003 + command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = False response_type: typing.ClassVar[str] = None @@ -41219,7 +41522,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: @dataclass class SetActiveDatasetRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000452 - command_id: typing.ClassVar[int] = 0x00000004 + command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True response_type: typing.ClassVar[str] = None @@ -41237,7 +41540,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: @dataclass class SetPendingDatasetRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000452 - command_id: typing.ClassVar[int] = 0x00000005 + command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = True response_type: typing.ClassVar[str] = None @@ -41323,7 +41626,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000005 + return 0x00000004 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -46067,6 +46370,244 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'uint' = 0 +@dataclass +class CommissionerControl(Cluster): + id: typing.ClassVar[int] = 0x00000751 + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="supportedDeviceCategories", Tag=0x00000000, Type=uint), + ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), + ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), + ]) + + supportedDeviceCategories: 'uint' = None + generatedCommandList: 'typing.List[uint]' = None + acceptedCommandList: 'typing.List[uint]' = None + eventList: 'typing.List[uint]' = None + attributeList: 'typing.List[uint]' = None + featureMap: 'uint' = None + clusterRevision: 'uint' = None + + class Bitmaps: + class SupportedDeviceCategoryBitmap(IntFlag): + kFabricSynchronization = 0x1 + + class Commands: + @dataclass + class RequestCommissioningApproval(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000751 + command_id: typing.ClassVar[int] = 0x00000000 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="requestId", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="vendorId", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="productId", Tag=2, Type=uint), + ClusterObjectFieldDescriptor(Label="label", Tag=3, Type=typing.Optional[str]), + ]) + + requestId: 'uint' = 0 + vendorId: 'uint' = 0 + productId: 'uint' = 0 + label: 'typing.Optional[str]' = None + + @dataclass + class CommissionNode(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000751 + command_id: typing.ClassVar[int] = 0x00000001 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'ReverseOpenCommissioningWindow' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="requestId", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="responseTimeoutSeconds", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="ipAddress", Tag=2, Type=typing.Optional[bytes]), + ClusterObjectFieldDescriptor(Label="port", Tag=3, Type=typing.Optional[uint]), + ]) + + requestId: 'uint' = 0 + responseTimeoutSeconds: 'uint' = 0 + ipAddress: 'typing.Optional[bytes]' = None + port: 'typing.Optional[uint]' = None + + @dataclass + class ReverseOpenCommissioningWindow(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000751 + command_id: typing.ClassVar[int] = 0x00000002 + is_client: typing.ClassVar[bool] = False + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="commissioningTimeout", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="PAKEPasscodeVerifier", Tag=1, Type=bytes), + ClusterObjectFieldDescriptor(Label="discriminator", Tag=2, Type=uint), + ClusterObjectFieldDescriptor(Label="iterations", Tag=3, Type=uint), + ClusterObjectFieldDescriptor(Label="salt", Tag=4, Type=bytes), + ]) + + commissioningTimeout: 'uint' = 0 + PAKEPasscodeVerifier: 'bytes' = b"" + discriminator: 'uint' = 0 + iterations: 'uint' = 0 + salt: 'bytes' = b"" + + class Attributes: + @dataclass + class SupportedDeviceCategories(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class GeneratedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF8 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AcceptedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF9 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class EventList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFA + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AttributeList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFB + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class FeatureMap(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFC + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class ClusterRevision(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFD + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + class Events: + @dataclass + class CommissioningRequestResult(ClusterEvent): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def event_id(cls) -> int: + return 0x00000000 + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="requestId", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="clientNodeId", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="statusCode", Tag=2, Type=uint), + ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), + ]) + + requestId: 'uint' = 0 + clientNodeId: 'uint' = 0 + statusCode: 'uint' = 0 + fabricIndex: 'uint' = 0 + + @dataclass class ElectricalMeasurement(Cluster): id: typing.ClassVar[int] = 0x00000B04 diff --git a/src/controller/python/chip/discovery/__init__.py b/src/controller/python/chip/discovery/__init__.py index a25fb490007824..c818b5e22358ac 100644 --- a/src/controller/python/chip/discovery/__init__.py +++ b/src/controller/python/chip/discovery/__init__.py @@ -92,7 +92,8 @@ class CommissionableNode(): mrpRetryIntervalIdle: int = None mrpRetryIntervalActive: int = None mrpRetryActiveThreshold: int = None - supportsTcp: bool = None + supportsTcpClient: bool = None + supportsTcpServer: bool = None isICDOperatingAsLIT: bool = None addresses: List[str] = None rotatingId: Optional[str] = None diff --git a/src/controller/python/chip/yaml/runner.py b/src/controller/python/chip/yaml/runner.py index 3081dad6248fa9..494e6f964aa33f 100644 --- a/src/controller/python/chip/yaml/runner.py +++ b/src/controller/python/chip/yaml/runner.py @@ -913,7 +913,8 @@ def decode(self, result: _ActionResult): 'mrpRetryIntervalIdle': response.mrpRetryIntervalIdle, 'mrpRetryIntervalActive': response.mrpRetryIntervalActive, 'mrpRetryActiveThreshold': response.mrpRetryActiveThreshold, - 'supportsTcp': response.supportsTcp, + 'supportsTcpClient': response.supportsTcpClient, + 'supportsTcpServer': response.supportsTcpServer, 'isICDOperatingAsLIT': response.isICDOperatingAsLIT, 'addresses': response.addresses, 'rotatingId': response.rotatingId, diff --git a/src/controller/python/test/test_scripts/mobile-device-test.py b/src/controller/python/test/test_scripts/mobile-device-test.py index 27f8e98964d7b9..39be65941a2a9f 100755 --- a/src/controller/python/test/test_scripts/mobile-device-test.py +++ b/src/controller/python/test/test_scripts/mobile-device-test.py @@ -19,6 +19,13 @@ # Commissioning test. +# test-runner-runs: run1 +# test-runner-run/run1/app: ${ALL_CLUSTERS_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --log-level INFO -t 3600 --disable-test ClusterObjectTests.TestTimedRequestTimeout --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto + import asyncio import os diff --git a/src/controller/tests/TestEventCaching.cpp b/src/controller/tests/TestEventCaching.cpp index b4c262725f74d3..e31e3ed358b6f0 100644 --- a/src/controller/tests/TestEventCaching.cpp +++ b/src/controller/tests/TestEventCaching.cpp @@ -16,8 +16,6 @@ * limitations under the License. */ -#include - #include "app-common/zap-generated/ids/Attributes.h" #include "app-common/zap-generated/ids/Clusters.h" #include "app/ClusterStateCache.h" @@ -37,7 +35,6 @@ #include #include #include -#include using namespace chip; using namespace chip::app; @@ -50,8 +47,6 @@ static uint8_t gInfoEventBuffer[4096]; static uint8_t gCritEventBuffer[4096]; static chip::app::CircularEventBuffer gCircularEventBuffer[3]; -using TestContext = chip::Test::AppContext; - // // The generated endpoint_config for the controller app has Endpoint 1 // already used in the fixed endpoint set of size 1. Consequently, let's use the next @@ -59,33 +54,10 @@ using TestContext = chip::Test::AppContext; // constexpr EndpointId kTestEndpointId = 2; -class TestEventCaching : public ::testing::Test +class TestEventCaching : public Test::AppContext { -public: - // Performs shared setup for all tests in the test suite - static void SetUpTestSuite() - { - if (mpContext == nullptr) - { - mpContext = new TestContext(); - ASSERT_NE(mpContext, nullptr); - } - mpContext->SetUpTestSuite(); - } - - // Performs shared teardown for all tests in the test suite - static void TearDownTestSuite() - { - mpContext->TearDownTestSuite(); - if (mpContext != nullptr) - { - delete mpContext; - mpContext = nullptr; - } - } - protected: - // Performs setup for each test in the suite + // Performs setup for each test in the suite. Run once for each test function. void SetUp() { const chip::app::LogStorageResources logStorageResources[] = { @@ -94,29 +66,24 @@ class TestEventCaching : public ::testing::Test { &gCritEventBuffer[0], sizeof(gCritEventBuffer), chip::app::PriorityLevel::Critical }, }; - mpContext->SetUp(); + AppContext::SetUp(); // Call parent. + VerifyOrReturn(!HasFailure()); // Stop if parent had a failure. - CHIP_ERROR err = CHIP_NO_ERROR; - // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete - VerifyOrDieWithMsg((err = mEventCounter.Init(0)) == CHIP_NO_ERROR, AppServer, - "Init EventCounter failed: %" CHIP_ERROR_FORMAT, err.Format()); - chip::app::EventManagement::CreateEventManagement(&mpContext->GetExchangeManager(), ArraySize(logStorageResources), + ASSERT_EQ(mEventCounter.Init(0), CHIP_NO_ERROR); + chip::app::EventManagement::CreateEventManagement(&GetExchangeManager(), ArraySize(logStorageResources), gCircularEventBuffer, logStorageResources, &mEventCounter); } - // Performs teardown for each test in the suite + // Performs teardown for each test in the suite. Run once for each test function. void TearDown() { chip::app::EventManagement::DestroyEventManagement(); - mpContext->TearDown(); + AppContext::TearDown(); // Call parent. } - static TestContext * mpContext; - private: MonotonicallyIncreasingCounter mEventCounter; }; -TestContext * TestEventCaching::mpContext = nullptr; //clang-format off DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(testClusterAttrs) @@ -179,7 +146,7 @@ void GenerateEvents(chip::EventNumber & firstEventNumber, chip::EventNumber & la */ TEST_F(TestEventCaching, TestBasicCaching) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -207,12 +174,12 @@ TEST_F(TestEventCaching, TestBasicCaching) TestReadCallback readCallback; { - app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), - readCallback.mClusterCacheAdapter.GetBufferedCallback(), app::ReadClient::InteractionType::Read); + app::ReadClient readClient(engine, &GetExchangeManager(), readCallback.mClusterCacheAdapter.GetBufferedCallback(), + app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); uint8_t generationCount = 0; readCallback.mClusterCacheAdapter.ForEachEventData( @@ -340,12 +307,12 @@ TEST_F(TestEventCaching, TestBasicCaching) GenerateEvents(firstEventNumber, lastEventNumber); { - app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), - readCallback.mClusterCacheAdapter.GetBufferedCallback(), app::ReadClient::InteractionType::Read); + app::ReadClient readClient(engine, &GetExchangeManager(), readCallback.mClusterCacheAdapter.GetBufferedCallback(), + app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // // Validate that we still have all 5 of the old events we received, as well as the new ones that just got generated. @@ -392,8 +359,8 @@ TEST_F(TestEventCaching, TestBasicCaching) // we don't receive events lower than that value. // { - app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), - readCallback.mClusterCacheAdapter.GetBufferedCallback(), app::ReadClient::InteractionType::Read); + app::ReadClient readClient(engine, &GetExchangeManager(), readCallback.mClusterCacheAdapter.GetBufferedCallback(), + app::ReadClient::InteractionType::Read); readCallback.mClusterCacheAdapter.ClearEventCache(); constexpr EventNumber kLastSeenEventNumber = 3; @@ -405,7 +372,7 @@ TEST_F(TestEventCaching, TestBasicCaching) EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // We should only get events with event numbers larger than kHighestEventNumberSeen. EXPECT_EQ(readCallback.mEventsSeen, lastEventNumber - kLastSeenEventNumber); @@ -441,12 +408,12 @@ TEST_F(TestEventCaching, TestBasicCaching) { readParams.mEventNumber.SetValue(5); - app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), - readCallback.mClusterCacheAdapter.GetBufferedCallback(), app::ReadClient::InteractionType::Read); + app::ReadClient readClient(engine, &GetExchangeManager(), readCallback.mClusterCacheAdapter.GetBufferedCallback(), + app::ReadClient::InteractionType::Read); readCallback.mClusterCacheAdapter.ClearEventCache(true); EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // // Validate that we would receive 5 events @@ -474,7 +441,7 @@ TEST_F(TestEventCaching, TestBasicCaching) EXPECT_TRUE(highestEventNumber.HasValue() && highestEventNumber.Value() == 9); } - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } diff --git a/src/controller/tests/TestEventChunking.cpp b/src/controller/tests/TestEventChunking.cpp index c7790959e6866e..fc71da8662596d 100644 --- a/src/controller/tests/TestEventChunking.cpp +++ b/src/controller/tests/TestEventChunking.cpp @@ -16,7 +16,7 @@ * limitations under the License. */ -#include +#include #include "app-common/zap-generated/ids/Attributes.h" #include "app-common/zap-generated/ids/Clusters.h" @@ -41,7 +41,6 @@ #include #include #include -#include using namespace chip; using namespace chip::app; @@ -54,8 +53,6 @@ static uint8_t gInfoEventBuffer[4096]; static uint8_t gCritEventBuffer[4096]; static chip::app::CircularEventBuffer gCircularEventBuffer[3]; -using TestContext = chip::Test::AppContext; - uint32_t gIterationCount = 0; // @@ -69,31 +66,8 @@ constexpr AttributeId kTestListLargeAttribute = 8; // This attribute will be lar // The size of the attribute which is a bit larger than the size of event used in the test. constexpr size_t kSizeOfLargeAttribute = 60; -class TestEventChunking : public ::testing::Test +class TestEventChunking : public chip::Test::AppContext { -public: - // Performs shared setup for all tests in the test suite - static void SetUpTestSuite() - { - if (mpContext == nullptr) - { - mpContext = new TestContext(); - ASSERT_NE(mpContext, nullptr); - } - mpContext->SetUpTestSuite(); - } - - // Performs shared teardown for all tests in the test suite - static void TearDownTestSuite() - { - mpContext->TearDownTestSuite(); - if (mpContext != nullptr) - { - delete mpContext; - mpContext = nullptr; - } - } - protected: // Performs setup for each test in the suite void SetUp() @@ -104,13 +78,13 @@ class TestEventChunking : public ::testing::Test { &gCritEventBuffer[0], sizeof(gCritEventBuffer), chip::app::PriorityLevel::Critical }, }; - mpContext->SetUp(); + AppContext::SetUp(); CHIP_ERROR err = CHIP_NO_ERROR; // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete VerifyOrDieWithMsg((err = mEventCounter.Init(0)) == CHIP_NO_ERROR, AppServer, "Init EventCounter failed: %" CHIP_ERROR_FORMAT, err.Format()); - chip::app::EventManagement::CreateEventManagement(&mpContext->GetExchangeManager(), ArraySize(logStorageResources), + chip::app::EventManagement::CreateEventManagement(&GetExchangeManager(), ArraySize(logStorageResources), gCircularEventBuffer, logStorageResources, &mEventCounter); } @@ -118,15 +92,12 @@ class TestEventChunking : public ::testing::Test void TearDown() { chip::app::EventManagement::DestroyEventManagement(); - mpContext->TearDown(); + AppContext::TearDown(); } - static TestContext * mpContext; - private: MonotonicallyIncreasingCounter mEventCounter; }; -TestContext * TestEventChunking::mpContext = nullptr; //clang-format off DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(testClusterAttrs) @@ -317,7 +288,7 @@ void GenerateEvents(chip::EventNumber & firstEventNumber, chip::EventNumber & la */ TEST_F(TestEventChunking, TestEventChunking) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -358,15 +329,15 @@ TEST_F(TestEventChunking, TestEventChunking) app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetWriterReserved(static_cast(800 + i)); - app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(readCallback.mEventCount, static_cast((lastEventNumber - firstEventNumber) + 1)); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); // // Stop the test if we detected an error. Otherwise, it'll be difficult to read the logs. @@ -383,7 +354,7 @@ TEST_F(TestEventChunking, TestEventChunking) // Similar to the tests above, but it will read attributes AND events TEST_F(TestEventChunking, TestMixedEventsAndAttributesChunking) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -426,12 +397,12 @@ TEST_F(TestEventChunking, TestMixedEventsAndAttributesChunking) app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetWriterReserved(static_cast(800 + i)); - app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // // Always returns the same number of attributes read (5 + revision + GlobalAttributesNotInMetadata). @@ -440,7 +411,7 @@ TEST_F(TestEventChunking, TestMixedEventsAndAttributesChunking) EXPECT_EQ(readCallback.mAttributeCount, 6 + ArraySize(GlobalAttributesNotInMetadata)); EXPECT_EQ(readCallback.mEventCount, static_cast(lastEventNumber - firstEventNumber + 1)); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); // // Stop the test if we detected an error. Otherwise, it'll be difficult to read the logs. @@ -459,7 +430,7 @@ TEST_F(TestEventChunking, TestMixedEventsAndAttributesChunking) // can be encoded in to one chunk in the tests above. This test will force it by reading only one attribtue and read many events. TEST_F(TestEventChunking, TestMixedEventsAndLargeAttributesChunking) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -502,18 +473,18 @@ TEST_F(TestEventChunking, TestMixedEventsAndLargeAttributesChunking) app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetWriterReserved(static_cast(800 + i)); - app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(readCallback.mOnReportEnd); EXPECT_EQ(readCallback.mAttributeCount, 1u); EXPECT_EQ(readCallback.mEventCount, static_cast(lastEventNumber - firstEventNumber + 1)); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); // // Stop the test if we detected an error. Otherwise, it'll be difficult to read the logs. diff --git a/src/controller/tests/TestEventNumberCaching.cpp b/src/controller/tests/TestEventNumberCaching.cpp index 4d77813262a691..344d8a26ed2653 100644 --- a/src/controller/tests/TestEventNumberCaching.cpp +++ b/src/controller/tests/TestEventNumberCaching.cpp @@ -16,7 +16,7 @@ * limitations under the License. */ -#include +#include #include "app-common/zap-generated/ids/Clusters.h" #include "app/ClusterStateCache.h" @@ -33,7 +33,6 @@ #include #include #include -#include using namespace chip; using namespace chip::app; @@ -46,8 +45,6 @@ static uint8_t gInfoEventBuffer[4096]; static uint8_t gCritEventBuffer[4096]; static chip::app::CircularEventBuffer gCircularEventBuffer[3]; -using TestContext = chip::Test::AppContext; - // // The generated endpoint_config for the controller app has Endpoint 1 // already used in the fixed endpoint set of size 1. Consequently, let's use the next @@ -55,31 +52,8 @@ using TestContext = chip::Test::AppContext; // constexpr EndpointId kTestEndpointId = 2; -class TestEventNumberCaching : public ::testing::Test +class TestEventNumberCaching : public chip::Test::AppContext { -public: - // Performs shared setup for all tests in the test suite - static void SetUpTestSuite() - { - if (mpContext == nullptr) - { - mpContext = new TestContext(); - ASSERT_NE(mpContext, nullptr); - } - mpContext->SetUpTestSuite(); - } - - // Performs shared teardown for all tests in the test suite - static void TearDownTestSuite() - { - mpContext->TearDownTestSuite(); - if (mpContext != nullptr) - { - delete mpContext; - mpContext = nullptr; - } - } - protected: // Performs setup for each test in the suite void SetUp() @@ -90,13 +64,13 @@ class TestEventNumberCaching : public ::testing::Test { &gCritEventBuffer[0], sizeof(gCritEventBuffer), chip::app::PriorityLevel::Critical }, }; - mpContext->SetUp(); + AppContext::SetUp(); CHIP_ERROR err = CHIP_NO_ERROR; // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete VerifyOrDieWithMsg((err = mEventCounter.Init(0)) == CHIP_NO_ERROR, AppServer, "Init EventCounter failed: %" CHIP_ERROR_FORMAT, err.Format()); - chip::app::EventManagement::CreateEventManagement(&mpContext->GetExchangeManager(), ArraySize(logStorageResources), + chip::app::EventManagement::CreateEventManagement(&GetExchangeManager(), ArraySize(logStorageResources), gCircularEventBuffer, logStorageResources, &mEventCounter); } @@ -104,15 +78,12 @@ class TestEventNumberCaching : public ::testing::Test void TearDown() { chip::app::EventManagement::DestroyEventManagement(); - mpContext->TearDown(); + AppContext::TearDown(); } - static TestContext * mpContext; - private: MonotonicallyIncreasingCounter mEventCounter; }; -TestContext * TestEventNumberCaching::mpContext = nullptr; //clang-format off DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(testClusterAttrs) @@ -168,7 +139,7 @@ void GenerateEvents(chip::EventNumber & firstEventNumber, chip::EventNumber & la */ TEST_F(TestEventNumberCaching, TestEventNumberCaching) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -199,12 +170,12 @@ TEST_F(TestEventNumberCaching, TestEventNumberCaching) Optional highestEventNumber; readCallback.mClusterCacheAdapter.GetHighestReceivedEventNumber(highestEventNumber); EXPECT_FALSE(highestEventNumber.HasValue()); - app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), - readCallback.mClusterCacheAdapter.GetBufferedCallback(), app::ReadClient::InteractionType::Read); + app::ReadClient readClient(engine, &GetExchangeManager(), readCallback.mClusterCacheAdapter.GetBufferedCallback(), + app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(readCallback.mEventsSeen, lastEventNumber - firstEventNumber + 1); @@ -223,8 +194,8 @@ TEST_F(TestEventNumberCaching, TestEventNumberCaching) // we don't receive events except ones larger than that value. // { - app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), - readCallback.mClusterCacheAdapter.GetBufferedCallback(), app::ReadClient::InteractionType::Read); + app::ReadClient readClient(engine, &GetExchangeManager(), readCallback.mClusterCacheAdapter.GetBufferedCallback(), + app::ReadClient::InteractionType::Read); readCallback.mClusterCacheAdapter.ClearEventCache(true); Optional highestEventNumber; @@ -242,7 +213,7 @@ TEST_F(TestEventNumberCaching, TestEventNumberCaching) EXPECT_FALSE(readParams.mEventNumber.HasValue()); EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // We should only get events with event numbers larger than kHighestEventNumberSeen. EXPECT_EQ(readCallback.mEventsSeen, lastEventNumber - kHighestEventNumberSeen); @@ -256,7 +227,7 @@ TEST_F(TestEventNumberCaching, TestEventNumberCaching) readCallback.mClusterCacheAdapter.GetHighestReceivedEventNumber(highestEventNumber); EXPECT_TRUE(highestEventNumber.HasValue() && highestEventNumber.Value() == lastEventNumber); } - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } diff --git a/src/controller/tests/TestReadChunking.cpp b/src/controller/tests/TestReadChunking.cpp index 8fe5e51c2b097f..b64e715e013660 100644 --- a/src/controller/tests/TestReadChunking.cpp +++ b/src/controller/tests/TestReadChunking.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include "app-common/zap-generated/ids/Attributes.h" #include "app-common/zap-generated/ids/Clusters.h" @@ -44,9 +44,7 @@ #include #include #include -#include -using TestContext = chip::Test::AppContext; using namespace chip; using namespace chip::app; using namespace chip::app::Clusters; @@ -72,42 +70,6 @@ constexpr AttributeId kTestBadAttribute = constexpr int kListAttributeItems = 5; -class TestReadChunking : public ::testing::Test -{ -public: - // Performs shared setup for all tests in the test suite - static void SetUpTestSuite() - { - if (mpContext == nullptr) - { - mpContext = new TestContext(); - ASSERT_NE(mpContext, nullptr); - } - mpContext->SetUpTestSuite(); - } - - // Performs shared teardown for all tests in the test suite - static void TearDownTestSuite() - { - mpContext->TearDownTestSuite(); - if (mpContext != nullptr) - { - delete mpContext; - mpContext = nullptr; - } - } - -protected: - // Performs setup for each test in the suite - void SetUp() { mpContext->SetUp(); } - - // Performs teardown for each test in the suite - void TearDown() { mpContext->TearDown(); } - - static TestContext * mpContext; -}; -TestContext * TestReadChunking::mpContext = nullptr; - //clang-format off DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(testClusterAttrs) DECLARE_DYNAMIC_ATTRIBUTE(0x00000001, INT8U, 1, 0), DECLARE_DYNAMIC_ATTRIBUTE(0x00000002, INT8U, 1, 0), @@ -492,6 +454,15 @@ void TestMutableReadCallback::OnAttributeData(const app::ConcreteDataAttributePa // Ignore all other attributes, we don't care above the global attributes. } +class TestReadChunking : public chip::Test::AppContext +{ +protected: + struct Instruction; + void DoTest(TestMutableReadCallback * callback, Instruction instruction); + void DriveIOUntilSubscriptionEstablished(TestMutableReadCallback * callback); + void DriveIOUntilEndOfReport(TestMutableReadCallback * callback); +}; + /* * This validates all the various corner cases encountered during chunking by * artificially reducing the size of a packet buffer used to encode attribute data @@ -511,7 +482,7 @@ void TestMutableReadCallback::OnAttributeData(const app::ConcreteDataAttributePa */ TEST_F(TestReadChunking, TestChunking) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -542,12 +513,12 @@ TEST_F(TestReadChunking, TestChunking) app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetWriterReserved(static_cast(850 + i)); - app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(readCallback.mOnReportEnd); // @@ -556,7 +527,7 @@ TEST_F(TestReadChunking, TestChunking) EXPECT_EQ(readCallback.mAttributeCount, 6 + ArraySize(GlobalAttributesNotInMetadata)); readCallback.mAttributeCount = 0; - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); // // Stop the test if we detected an error. Otherwise, it'll be difficult to read the logs. @@ -573,7 +544,7 @@ TEST_F(TestReadChunking, TestChunking) // Similar to the test above, but for the list chunking feature. TEST_F(TestReadChunking, TestListChunking) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -617,12 +588,12 @@ TEST_F(TestReadChunking, TestListChunking) app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetWriterReserved( static_cast(maxPacketSize - packetSize)); - app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Up until our packets are big enough, we might just keep getting // errors due to the inability to encode even a single IB in a packet. @@ -654,7 +625,7 @@ TEST_F(TestReadChunking, TestListChunking) EXPECT_FALSE(readCallback.mBufferedCallback.mSawEmptyList); } - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); // // Stop the test if we detected an error. Otherwise, it'll be difficult to read the logs. @@ -674,7 +645,7 @@ TEST_F(TestReadChunking, TestListChunking) // Read an attribute that can never fit into the buffer. Result in an empty report, server should shutdown the transaction. TEST_F(TestReadChunking, TestBadChunking) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -695,12 +666,12 @@ TEST_F(TestReadChunking, TestBadChunking) TestReadCallback readCallback; { - app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // The server should return an empty list as attribute data for the first report (for list chunking), and encodes nothing // (then shuts down the read handler) for the second report. @@ -711,11 +682,11 @@ TEST_F(TestReadChunking, TestBadChunking) EXPECT_FALSE(readCallback.mOnReportEnd); // The server should shutted down, while the client is still alive (pending for the attribute data.) - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // Sanity check - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } @@ -725,7 +696,7 @@ TEST_F(TestReadChunking, TestBadChunking) */ TEST_F(TestReadChunking, TestDynamicEndpoint) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -745,21 +716,21 @@ TEST_F(TestReadChunking, TestDynamicEndpoint) { - app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Subscribe); // Enable the new endpoint emberAfSetDynamicEndpoint(0, kTestEndpointId, &testEndpoint, Span(dataVersionStorage)); EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(readCallback.mOnSubscriptionEstablished); readCallback.mAttributeCount = 0; emberAfSetDynamicEndpoint(0, kTestEndpointId4, &testEndpoint4, Span(dataVersionStorage)); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Ensure we have received the report, we do not care about the initial report here. // GlobalAttributesNotInMetadata attributes are not included in testClusterAttrsOnEndpoint4. @@ -774,7 +745,7 @@ TEST_F(TestReadChunking, TestDynamicEndpoint) // Disable the new endpoint emberAfEndpointEnableDisable(kTestEndpointId4, false); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // We may receive some attribute reports for descriptor cluster, but we do not care about it for now. @@ -784,7 +755,7 @@ TEST_F(TestReadChunking, TestDynamicEndpoint) readCallback.mOnReportEnd = false; emberAfEndpointEnableDisable(kTestEndpointId4, true); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Ensure we have received the report, we do not care about the initial report here. // GlobalAttributesNotInMetadata attributes are not included in testClusterAttrsOnEndpoint4. @@ -797,9 +768,9 @@ TEST_F(TestReadChunking, TestDynamicEndpoint) chip::test_utils::SleepMillis(SecondsToMilliseconds(2)); // Destroying the read client will terminate the subscription transaction. - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } @@ -845,57 +816,59 @@ enum AttrIds using AttributeWithValue = std::pair; using AttributesList = std::vector; -struct Instruction +void CheckValues(TestMutableReadCallback * callback, std::vector expectedValues = {}) +{ + for (const auto & vals : expectedValues) + { + EXPECT_EQ(callback->mValues[vals.first], vals.second); + } +} + +void ExpectSameDataVersions(TestMutableReadCallback * callback, AttributesList attrList) +{ + if (attrList.size() == 0) + { + return; + } + DataVersion expectedVersion = callback->mDataVersions[attrList[0]]; + for (const auto & attr : attrList) + { + EXPECT_EQ(callback->mDataVersions[attr], expectedVersion); + } +} + +}; // namespace TestSetDirtyBetweenChunksUtil + +struct TestReadChunking::Instruction { // The maximum number of attributes should be iterated in a single report chunk. uint32_t chunksize; // A list of functions that will be executed before driving the main loop. std::vector> preworks; // A list of pair for attributes and their expected values in the report. - std::vector expectedValues; + std::vector expectedValues; // A list of list of various attributes which should have the same data version in the report. - std::vector attributesWithSameDataVersion; + std::vector attributesWithSameDataVersion; }; -void DriveIOUntilSubscriptionEstablished(TestContext * pContext, TestMutableReadCallback * callback) +void TestReadChunking::DriveIOUntilSubscriptionEstablished(TestMutableReadCallback * callback) { callback->mOnReportEnd = false; - pContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return callback->mOnSubscriptionEstablished; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return callback->mOnSubscriptionEstablished; }); EXPECT_TRUE(callback->mOnReportEnd); EXPECT_TRUE(callback->mOnSubscriptionEstablished); callback->mActionOn.clear(); } -void DriveIOUntilEndOfReport(TestContext * pContext, TestMutableReadCallback * callback) +void TestReadChunking::DriveIOUntilEndOfReport(TestMutableReadCallback * callback) { callback->mOnReportEnd = false; - pContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return callback->mOnReportEnd; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return callback->mOnReportEnd; }); EXPECT_TRUE(callback->mOnReportEnd); callback->mActionOn.clear(); } -void CheckValues(TestMutableReadCallback * callback, std::vector expectedValues = {}) -{ - for (const auto & vals : expectedValues) - { - EXPECT_EQ(callback->mValues[vals.first], vals.second); - } -} - -void ExpectSameDataVersions(TestMutableReadCallback * callback, AttributesList attrList) -{ - if (attrList.size() == 0) - { - return; - } - DataVersion expectedVersion = callback->mDataVersions[attrList[0]]; - for (const auto & attr : attrList) - { - EXPECT_EQ(callback->mDataVersions[attr], expectedVersion); - } -} - -void DoTest(TestContext * pContext, TestMutableReadCallback * callback, Instruction instruction) +void TestReadChunking::DoTest(TestMutableReadCallback * callback, Instruction instruction) { app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetMaxAttributesPerChunk(instruction.chunksize); @@ -904,22 +877,20 @@ void DoTest(TestContext * pContext, TestMutableReadCallback * callback, Instruct act(); } - DriveIOUntilEndOfReport(pContext, callback); + DriveIOUntilEndOfReport(callback); - CheckValues(callback, instruction.expectedValues); + TestSetDirtyBetweenChunksUtil::CheckValues(callback, instruction.expectedValues); for (const auto & attrList : instruction.attributesWithSameDataVersion) { - ExpectSameDataVersions(callback, attrList); + TestSetDirtyBetweenChunksUtil::ExpectSameDataVersions(callback, attrList); } } -}; // namespace TestSetDirtyBetweenChunksUtil - TEST_F(TestReadChunking, TestSetDirtyBetweenChunks) { using namespace TestSetDirtyBetweenChunksUtil; - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -953,7 +924,7 @@ TEST_F(TestReadChunking, TestSetDirtyBetweenChunks) gIterationCount = 1; - app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Subscribe); EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); @@ -965,11 +936,11 @@ TEST_F(TestReadChunking, TestSetDirtyBetweenChunks) // We are expected to miss attributes on kTestEndpointId during initial reports. ChipLogProgress(DataManagement, "Case 1-1: Set dirty during priming report."); readCallback.mActionOn[AttrOnEp5] = TouchAttrOp(AttrOnEp1); - DriveIOUntilSubscriptionEstablished(mpContext, &readCallback); + DriveIOUntilSubscriptionEstablished(&readCallback); CheckValues(&readCallback, { { AttrOnEp1, 1 } }); ChipLogProgress(DataManagement, "Case 1-2: Check for attributes missed last report."); - DoTest(mpContext, &readCallback, Instruction{ .chunksize = 2, .expectedValues = { { AttrOnEp1, 2 } } }); + DoTest(&readCallback, Instruction{ .chunksize = 2, .expectedValues = { { AttrOnEp1, 2 } } }); } // CASE 2 -- Set dirty during chunked report, the attribute is already dirty. @@ -977,7 +948,7 @@ TEST_F(TestReadChunking, TestSetDirtyBetweenChunks) ChipLogProgress(DataManagement, "Case 2: Set dirty during chunked report by wildcard path."); readCallback.mActionOn[AttrOnEp5] = WriteAttrOp(AttrOnEp5, 3); DoTest( - mpContext, &readCallback, + &readCallback, Instruction{ .chunksize = 2, .preworks = { WriteAttrOp(AttrOnEp5, 2), WriteAttrOp(AttrOnEp5, 2), WriteAttrOp(AttrOnEp5, 2) }, @@ -991,7 +962,7 @@ TEST_F(TestReadChunking, TestSetDirtyBetweenChunks) "Case 3-1: Set dirty during chunked report by wildcard path -- new dirty attribute."); readCallback.mActionOn[AttrOnEp5] = WriteAttrOp(AttrOnEp5, 4); DoTest( - mpContext, &readCallback, + &readCallback, Instruction{ .chunksize = 1, .preworks = { WriteAttrOp(AttrOnEp5, 4), WriteAttrOp(AttrOnEp5, 4) }, .expectedValues = { { AttrOnEp5, 4 }, { AttrOnEp5, 4 }, { AttrOnEp5, 4 } }, @@ -1002,7 +973,7 @@ TEST_F(TestReadChunking, TestSetDirtyBetweenChunks) app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetMaxAttributesPerChunk(1); readCallback.mActionOn[AttrOnEp5] = WriteAttrOp(AttrOnEp5, 5); DoTest( - mpContext, &readCallback, + &readCallback, Instruction{ .chunksize = 1, .preworks = { WriteAttrOp(AttrOnEp5, 5), WriteAttrOp(AttrOnEp5, 5) }, .expectedValues = { { AttrOnEp5, 5 }, { AttrOnEp5, 5 }, { AttrOnEp5, 5 } }, @@ -1032,18 +1003,18 @@ TEST_F(TestReadChunking, TestSetDirtyBetweenChunks) { TestMutableReadCallback readCallback; - app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Subscribe); EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - DriveIOUntilSubscriptionEstablished(mpContext, &readCallback); + DriveIOUntilSubscriptionEstablished(&readCallback); // Note, although the two attributes comes from the same cluster, they are generated by different interested paths. // In this case, we won't reset the path iterator. ChipLogProgress(DataManagement, "Case 1-1: Test set dirty during reports generated by concrete paths."); readCallback.mActionOn[AttrOnEp5] = WriteAttrOp(AttrOnEp5, 4); - DoTest(mpContext, &readCallback, + DoTest(&readCallback, Instruction{ .chunksize = 1, .preworks = { WriteAttrOp(AttrOnEp5, 3), WriteAttrOp(AttrOnEp5, 3), WriteAttrOp(AttrOnEp5, 3) }, @@ -1051,16 +1022,16 @@ TEST_F(TestReadChunking, TestSetDirtyBetweenChunks) // The attribute failed to catch last report will be picked by this report. ChipLogProgress(DataManagement, "Case 1-2: Check for attributes missed last report."); - DoTest(mpContext, &readCallback, { .chunksize = 1, .expectedValues = { { AttrOnEp5, 4 } } }); + DoTest(&readCallback, { .chunksize = 1, .expectedValues = { { AttrOnEp5, 4 } } }); } } chip::test_utils::SleepMillis(SecondsToMilliseconds(3)); // Destroying the read client will terminate the subscription transaction. - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(1); emberAfClearDynamicEndpoint(0); diff --git a/src/controller/tests/TestServerCommandDispatch.cpp b/src/controller/tests/TestServerCommandDispatch.cpp index 41fab0ae0e3802..e1a266c5f99d66 100644 --- a/src/controller/tests/TestServerCommandDispatch.cpp +++ b/src/controller/tests/TestServerCommandDispatch.cpp @@ -22,7 +22,7 @@ * */ -#include +#include #include "app-common/zap-generated/ids/Attributes.h" #include "app-common/zap-generated/ids/Clusters.h" @@ -36,9 +36,6 @@ #include #include #include -#include - -using TestContext = chip::Test::AppContext; using namespace chip; using namespace chip::app; @@ -130,45 +127,11 @@ CHIP_ERROR TestClusterCommandHandler::EnumerateAcceptedCommands(const ConcreteCl namespace { -class TestServerCommandDispatch : public ::testing::Test +class TestServerCommandDispatch : public chip::Test::AppContext { -public: - // Performs shared setup for all tests in the test suite - static void SetUpTestSuite() - { - if (mpContext == nullptr) - { - mpContext = new TestContext(); - ASSERT_NE(mpContext, nullptr); - } - mpContext->SetUpTestSuite(); - } - - // Performs shared teardown for all tests in the test suite - static void TearDownTestSuite() - { - mpContext->TearDownTestSuite(); - if (mpContext != nullptr) - { - delete mpContext; - mpContext = nullptr; - } - } - protected: - // Performs setup for each test in the suite - void SetUp() { mpContext->SetUp(); } - - // Performs teardown for each test in the suite - void TearDown() { mpContext->TearDown(); } - - static TestContext * mpContext; - - // Helpers - - static void TestDataResponseHelper(const EmberAfEndpointType * aEndpoint, bool aExpectSuccess); + void TestDataResponseHelper(const EmberAfEndpointType * aEndpoint, bool aExpectSuccess); }; -TestContext * TestServerCommandDispatch::mpContext = nullptr; // We want to send a TestSimpleArgumentRequest::Type, but get a // TestStructArrayArgumentResponse in return, so need to shadow the actual @@ -181,7 +144,7 @@ struct FakeRequest : public Clusters::UnitTesting::Commands::TestSimpleArgumentR TEST_F(TestServerCommandDispatch, TestNoHandler) { FakeRequest request; - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); request.arg1 = true; @@ -203,12 +166,12 @@ TEST_F(TestServerCommandDispatch, TestNoHandler) responseDirective = kSendDataResponse; - chip::Controller::InvokeCommandRequest(&mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, + chip::Controller::InvokeCommandRequest(&GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } static const int kDescriptorAttributeArraySize = 254; @@ -261,7 +224,7 @@ DECLARE_DYNAMIC_ENDPOINT(testEndpoint3, testEndpointClusters3); void TestServerCommandDispatch::TestDataResponseHelper(const EmberAfEndpointType * aEndpoint, bool aExpectSuccess) { FakeRequest request; - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessWasCalled = false; bool onFailureWasCalled = false; @@ -307,13 +270,13 @@ void TestServerCommandDispatch::TestDataResponseHelper(const EmberAfEndpointType responseDirective = kSendDataResponse; - chip::Controller::InvokeCommandRequest(&mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, + chip::Controller::InvokeCommandRequest(&GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(onSuccessWasCalled == aExpectSuccess && onFailureWasCalled != aExpectSuccess); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); onSuccessWasCalled = false; onFailureWasCalled = false; @@ -346,12 +309,12 @@ void TestServerCommandDispatch::TestDataResponseHelper(const EmberAfEndpointType }; chip::Controller::ReadAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, readSuccessCb, readFailureCb); + &GetExchangeManager(), sessionHandle, kTestEndpointId, readSuccessCb, readFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(onSuccessWasCalled && !onFailureWasCalled); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } diff --git a/src/controller/tests/TestWriteChunking.cpp b/src/controller/tests/TestWriteChunking.cpp index 60be2212aa00e8..dcb4b36044c985 100644 --- a/src/controller/tests/TestWriteChunking.cpp +++ b/src/controller/tests/TestWriteChunking.cpp @@ -19,8 +19,6 @@ #include #include -#include - #include "app-common/zap-generated/ids/Attributes.h" #include "app-common/zap-generated/ids/Clusters.h" #include "app/ConcreteAttributePath.h" @@ -38,9 +36,7 @@ #include #include #include -#include -using TestContext = chip::Test::AppContext; using namespace chip; using namespace chip::app; using namespace chip::app::Clusters; @@ -62,41 +58,39 @@ constexpr uint32_t kTestListLength = 5; // We don't really care about the content, we just need a buffer. uint8_t sByteSpanData[app::kMaxSecureSduLengthBytes]; -class TestWriteChunking : public ::testing::Test +class TestWriteChunking : public Test::AppContext { -public: - // Performs shared setup for all tests in the test suite - static void SetUpTestSuite() - { - if (mpContext == nullptr) - { - mpContext = new TestContext(); - ASSERT_NE(mpContext, nullptr); - } - mpContext->SetUpTestSuite(); - } +private: + using PathStatus = std::pair; - // Performs shared teardown for all tests in the test suite - static void TearDownTestSuite() +protected: + enum class Operations : uint8_t { - mpContext->TearDownTestSuite(); - if (mpContext != nullptr) - { - delete mpContext; - mpContext = nullptr; - } - } + kNoop, + kShutdownWriteClient, + }; -protected: - // Performs setup for each test in the suite - void SetUp() { mpContext->SetUp(); } + enum class ListData : uint8_t + { + kNull, + kList, + kBadValue, + }; - // Performs teardown for each test in the suite - void TearDown() { mpContext->TearDown(); } + struct Instructions + { + // The paths used in write request + std::vector paths; + // The type of content of the list, it should be an empty vector or its size should equals to the list of paths. + std::vector data; + // operations on OnListWriteBegin and OnListWriteEnd on the server side. + std::function onListWriteBeginActions; + // The expected status when OnListWriteEnd is called. In the same order as paths + std::vector expectedStatus; + }; - static TestContext * mpContext; + void RunTest(Instructions instructions); }; -TestContext * TestWriteChunking::mpContext = nullptr; //clang-format off DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(testClusterAttrsOnEndpoint) @@ -211,7 +205,7 @@ CHIP_ERROR TestAttrAccess::Write(const app::ConcreteDataAttributePath & aPath, a */ TEST_F(TestWriteChunking, TestListChunking) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); // Initialize the ember side server logic InitDataModelHandler(); @@ -238,7 +232,7 @@ TEST_F(TestWriteChunking, TestListChunking) gIterationCount = i; - app::WriteClient writeClient(&mpContext->GetExchangeManager(), &writeCallback, Optional::Missing(), + app::WriteClient writeClient(&GetExchangeManager(), &writeCallback, Optional::Missing(), static_cast(minReservationSize + i) /* reserved buffer size */); ByteSpan list[kTestListLength]; @@ -256,14 +250,14 @@ TEST_F(TestWriteChunking, TestListChunking) // for (int j = 0; j < 10 && writeCallback.mOnDoneCount == 0; j++) { - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); } EXPECT_EQ(writeCallback.mSuccessCount, kTestListLength + 1 /* an extra item for the empty list at the beginning */); EXPECT_EQ(writeCallback.mErrorCount, 0u); EXPECT_EQ(writeCallback.mOnDoneCount, 1u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); // // Stop the test if we detected an error. Otherwise, it'll be difficult to read the logs. @@ -281,7 +275,7 @@ TEST_F(TestWriteChunking, TestListChunking) // As the actual overhead may change, we will test over a few possible payload lengths, from 850 to MTU used in write clients. TEST_F(TestWriteChunking, TestBadChunking) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool atLeastOneRequestSent = false; bool atLeastOneRequestFailed = false; @@ -306,7 +300,7 @@ TEST_F(TestWriteChunking, TestBadChunking) gIterationCount = (uint32_t) i; - app::WriteClient writeClient(&mpContext->GetExchangeManager(), &writeCallback, Optional::Missing()); + app::WriteClient writeClient(&GetExchangeManager(), &writeCallback, Optional::Missing()); ByteSpan list[kTestListLength]; for (auto & item : list) @@ -335,14 +329,14 @@ TEST_F(TestWriteChunking, TestBadChunking) // for (int j = 0; j < 10 && writeCallback.mOnDoneCount == 0; j++) { - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); } EXPECT_EQ(writeCallback.mSuccessCount, kTestListLength + 1 /* an extra item for the empty list at the beginning */); EXPECT_EQ(writeCallback.mErrorCount, 0u); EXPECT_EQ(writeCallback.mOnDoneCount, 1u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); // // Stop the test if we detected an error. Otherwise, it'll be difficult to read the logs. @@ -352,7 +346,7 @@ TEST_F(TestWriteChunking, TestBadChunking) break; } } - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); EXPECT_TRUE(atLeastOneRequestSent && atLeastOneRequestFailed); emberAfClearDynamicEndpoint(0); } @@ -363,7 +357,7 @@ TEST_F(TestWriteChunking, TestBadChunking) */ TEST_F(TestWriteChunking, TestConflictWrite) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); // Initialize the ember side server logic InitDataModelHandler(); @@ -380,11 +374,11 @@ TEST_F(TestWriteChunking, TestConflictWrite) constexpr size_t kReserveSize = kMaxSecureSduLengthBytes - 128; TestWriteCallback writeCallback1; - app::WriteClient writeClient1(&mpContext->GetExchangeManager(), &writeCallback1, Optional::Missing(), + app::WriteClient writeClient1(&GetExchangeManager(), &writeCallback1, Optional::Missing(), static_cast(kReserveSize)); TestWriteCallback writeCallback2; - app::WriteClient writeClient2(&mpContext->GetExchangeManager(), &writeCallback2, Optional::Missing(), + app::WriteClient writeClient2(&GetExchangeManager(), &writeCallback2, Optional::Missing(), static_cast(kReserveSize)); ByteSpan list[kTestListLength]; @@ -402,7 +396,7 @@ TEST_F(TestWriteChunking, TestConflictWrite) err = writeClient2.SendWriteRequest(sessionHandle); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); { const TestWriteCallback * writeCallbackRef1 = &writeCallback1; @@ -426,7 +420,7 @@ TEST_F(TestWriteChunking, TestConflictWrite) EXPECT_EQ(writeCallbackRef2->mOnDoneCount, 1u); } - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } @@ -437,7 +431,7 @@ TEST_F(TestWriteChunking, TestConflictWrite) */ TEST_F(TestWriteChunking, TestNonConflictWrite) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); // Initialize the ember side server logic InitDataModelHandler(); @@ -455,11 +449,11 @@ TEST_F(TestWriteChunking, TestNonConflictWrite) constexpr size_t kReserveSize = kMaxSecureSduLengthBytes - 128; TestWriteCallback writeCallback1; - app::WriteClient writeClient1(&mpContext->GetExchangeManager(), &writeCallback1, Optional::Missing(), + app::WriteClient writeClient1(&GetExchangeManager(), &writeCallback1, Optional::Missing(), static_cast(kReserveSize)); TestWriteCallback writeCallback2; - app::WriteClient writeClient2(&mpContext->GetExchangeManager(), &writeCallback2, Optional::Missing(), + app::WriteClient writeClient2(&GetExchangeManager(), &writeCallback2, Optional::Missing(), static_cast(kReserveSize)); ByteSpan list[kTestListLength]; @@ -477,7 +471,7 @@ TEST_F(TestWriteChunking, TestNonConflictWrite) err = writeClient2.SendWriteRequest(sessionHandle); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); { EXPECT_EQ(writeCallback1.mErrorCount, 0u); @@ -489,48 +483,19 @@ TEST_F(TestWriteChunking, TestNonConflictWrite) EXPECT_EQ(writeCallback2.mOnDoneCount, 1u); } - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } -namespace TestTransactionalListInstructions { - -using PathStatus = std::pair; - -enum class Operations : uint8_t -{ - kNoop, - kShutdownWriteClient, -}; - -enum class ListData : uint8_t -{ - kNull, - kList, - kBadValue, -}; - -struct Instructions -{ - // The paths used in write request - std::vector paths; - // The type of content of the list, it should be an empty vector or its size should equals to the list of paths. - std::vector data; - // operations on OnListWriteBegin and OnListWriteEnd on the server side. - std::function onListWriteBeginActions; - // The expected status when OnListWriteEnd is called. In the same order as paths - std::vector expectedStatus; -}; - -void RunTest(TestContext * pContext, Instructions instructions) +void TestWriteChunking::RunTest(Instructions instructions) { CHIP_ERROR err = CHIP_NO_ERROR; - auto sessionHandle = pContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); TestWriteCallback writeCallback; std::unique_ptr writeClient = std::make_unique( - &pContext->GetExchangeManager(), &writeCallback, Optional::Missing(), + &GetExchangeManager(), &writeCallback, Optional::Missing(), static_cast(kMaxSecureSduLengthBytes - 128) /* use a smaller chunk so we only need a few attributes in the write request. */); @@ -598,9 +563,9 @@ void RunTest(TestContext * pContext, Instructions instructions) err = writeClient->SendWriteRequest(sessionHandle); EXPECT_EQ(err, CHIP_NO_ERROR); - pContext->GetIOContext().DriveIOUntil(sessionHandle->ComputeRoundTripTimeout(app::kExpectedIMProcessingTime) + - System::Clock::Seconds16(1), - [&]() { return pContext->GetExchangeManager().GetNumActiveExchanges() == 0; }); + GetIOContext().DriveIOUntil(sessionHandle->ComputeRoundTripTimeout(app::kExpectedIMProcessingTime) + + System::Clock::Seconds16(1), + [&]() { return GetExchangeManager().GetNumActiveExchanges() == 0; }); EXPECT_EQ(onGoingPath, app::ConcreteAttributePath()); EXPECT_EQ(status.size(), instructions.expectedStatus.size()); @@ -614,12 +579,8 @@ void RunTest(TestContext * pContext, Instructions instructions) testServer.mOnListWriteEnd = nullptr; } -} // namespace TestTransactionalListInstructions - TEST_F(TestWriteChunking, TestTransactionalList) { - using namespace TestTransactionalListInstructions; - // Initialize the ember side server logic InitDataModelHandler(); @@ -631,98 +592,88 @@ TEST_F(TestWriteChunking, TestTransactionalList) // Test 1: we should receive transaction notifications ChipLogProgress(Zcl, "Test 1: we should receive transaction notifications"); - RunTest(mpContext, - Instructions{ - .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, - .expectedStatus = { true }, - }); + RunTest(Instructions{ + .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, + .expectedStatus = { true }, + }); ChipLogProgress(Zcl, "Test 2: we should receive transaction notifications for incomplete list operations"); - RunTest( - mpContext, - Instructions{ - .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, - .onListWriteBeginActions = [&](const app::ConcreteAttributePath & aPath) { return Operations::kShutdownWriteClient; }, - .expectedStatus = { false }, - }); + RunTest(Instructions{ + .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, + .onListWriteBeginActions = [&](const app::ConcreteAttributePath & aPath) { return Operations::kShutdownWriteClient; }, + .expectedStatus = { false }, + }); ChipLogProgress(Zcl, "Test 3: we should receive transaction notifications for every list in the transaction"); - RunTest(mpContext, - Instructions{ - .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), - ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute2) }, - .expectedStatus = { true, true }, - }); + RunTest(Instructions{ + .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), + ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute2) }, + .expectedStatus = { true, true }, + }); ChipLogProgress(Zcl, "Test 4: we should receive transaction notifications with the status of each list"); - RunTest(mpContext, - Instructions{ - .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), - ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute2) }, - .onListWriteBeginActions = - [&](const app::ConcreteAttributePath & aPath) { - if (aPath.mAttributeId == kTestListAttribute2) - { - return Operations::kShutdownWriteClient; - } - return Operations::kNoop; - }, - .expectedStatus = { true, false }, - }); + RunTest(Instructions{ + .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), + ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute2) }, + .onListWriteBeginActions = + [&](const app::ConcreteAttributePath & aPath) { + if (aPath.mAttributeId == kTestListAttribute2) + { + return Operations::kShutdownWriteClient; + } + return Operations::kNoop; + }, + .expectedStatus = { true, false }, + }); ChipLogProgress(Zcl, "Test 5: transactional list callbacks will be called for nullable lists, test if it is handled correctly for " "null value before non null values"); - RunTest(mpContext, - Instructions{ - .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), - ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, - .data = { ListData::kNull, ListData::kList }, - .expectedStatus = { true }, - }); + RunTest(Instructions{ + .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), + ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, + .data = { ListData::kNull, ListData::kList }, + .expectedStatus = { true }, + }); ChipLogProgress(Zcl, "Test 6: transactional list callbacks will be called for nullable lists, test if it is handled correctly for " "null value after non null values"); - RunTest(mpContext, - Instructions{ - .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), - ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, - .data = { ListData::kList, ListData::kNull }, - .expectedStatus = { true }, - }); + RunTest(Instructions{ + .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), + ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, + .data = { ListData::kList, ListData::kNull }, + .expectedStatus = { true }, + }); ChipLogProgress(Zcl, "Test 7: transactional list callbacks will be called for nullable lists, test if it is handled correctly for " "null value between non null values"); - RunTest(mpContext, - Instructions{ - .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), - ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), - ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, - .data = { ListData::kList, ListData::kNull, ListData::kList }, - .expectedStatus = { true }, - }); + RunTest(Instructions{ + .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), + ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), + ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, + .data = { ListData::kList, ListData::kNull, ListData::kList }, + .expectedStatus = { true }, + }); ChipLogProgress(Zcl, "Test 8: transactional list callbacks will be called for nullable lists"); - RunTest(mpContext, - Instructions{ - .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, - .data = { ListData::kNull }, - .expectedStatus = { true }, - }); + RunTest(Instructions{ + .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, + .data = { ListData::kNull }, + .expectedStatus = { true }, + }); ChipLogProgress(Zcl, "Test 9: for nullable lists, we should receive notifications for unsuccessful writes when non-fatal occurred " "during processing the requests"); - RunTest(mpContext, - Instructions{ - .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, - .data = { ListData::kBadValue }, - .expectedStatus = { false }, - }); - - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + RunTest(Instructions{ + .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, + .data = { ListData::kBadValue }, + .expectedStatus = { false }, + }); + + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } diff --git a/src/controller/tests/data_model/TestCommands.cpp b/src/controller/tests/data_model/TestCommands.cpp index 2ccb98d5cf7e00..0f6166cfed59b9 100644 --- a/src/controller/tests/data_model/TestCommands.cpp +++ b/src/controller/tests/data_model/TestCommands.cpp @@ -42,8 +42,6 @@ #include #include -using TestContext = chip::Test::AppContext; - using namespace chip; using namespace chip::app; using namespace chip::app::Clusters; @@ -52,34 +50,7 @@ using namespace chip::Protocols; namespace { -class TestCommands : public ::testing::Test -{ -public: - // Performs shared setup for all tests in the test suite - static void SetUpTestSuite() - { - mpContext = new TestContext(); - ASSERT_NE(mpContext, nullptr); - mpContext->SetUpTestSuite(); - } - - // Performs shared teardown for all tests in the test suite - static void TearDownTestSuite() - { - mpContext->TearDownTestSuite(); - delete mpContext; - } - -protected: - // Performs setup for each individual test in the test suite - void SetUp() { mpContext->SetUp(); } - - // Performs teardown for each individual test in the test suite - void TearDown() { mpContext->TearDown(); } - - static TestContext * mpContext; -}; -TestContext * TestCommands::mpContext = nullptr; +using TestCommands = chip::Test::AppContext; TEST_F(TestCommands, TestDataResponse) { @@ -92,7 +63,7 @@ TEST_F(TestCommands, TestDataResponse) }; FakeRequest request; - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessWasCalled = false; bool onFailureWasCalled = false; @@ -128,13 +99,13 @@ TEST_F(TestCommands, TestDataResponse) ScopedChange directive(gCommandResponseDirective, CommandResponseDirective::kSendDataResponse); - chip::Controller::InvokeCommandRequest(&mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, + chip::Controller::InvokeCommandRequest(&GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(onSuccessWasCalled && !onFailureWasCalled); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommands, TestSuccessNoDataResponse) @@ -145,7 +116,7 @@ TEST_F(TestCommands, TestSuccessNoDataResponse) }; FakeRequest request; - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessWasCalled = false; bool onFailureWasCalled = false; @@ -166,13 +137,13 @@ TEST_F(TestCommands, TestSuccessNoDataResponse) ScopedChange directive(gCommandResponseDirective, CommandResponseDirective::kSendSuccessStatusCode); - chip::Controller::InvokeCommandRequest(&mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, + chip::Controller::InvokeCommandRequest(&GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(onSuccessWasCalled && !onFailureWasCalled && statusCheck); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommands, TestMultipleSuccessNoDataResponses) @@ -183,7 +154,7 @@ TEST_F(TestCommands, TestMultipleSuccessNoDataResponses) }; FakeRequest request; - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); size_t successCalls = 0; size_t failureCalls = 0; @@ -204,14 +175,13 @@ TEST_F(TestCommands, TestMultipleSuccessNoDataResponses) ScopedChange directive(gCommandResponseDirective, CommandResponseDirective::kSendMultipleSuccessStatusCodes); - Controller::InvokeCommandRequest(&mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, - onFailureCb); + Controller::InvokeCommandRequest(&GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(successCalls == 1 && statusCheck); EXPECT_EQ(failureCalls, 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommands, TestAsyncResponse) @@ -222,7 +192,7 @@ TEST_F(TestCommands, TestAsyncResponse) }; FakeRequest request; - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessWasCalled = false; bool onFailureWasCalled = false; @@ -243,13 +213,13 @@ TEST_F(TestCommands, TestAsyncResponse) ScopedChange directive(gCommandResponseDirective, CommandResponseDirective::kAsync); - chip::Controller::InvokeCommandRequest(&mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, + chip::Controller::InvokeCommandRequest(&GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(!onSuccessWasCalled && !onFailureWasCalled && !statusCheck); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 2u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 2u); CommandHandler * commandHandle = gAsyncCommandHandle.Get(); ASSERT_NE(commandHandle, nullptr); @@ -258,16 +228,16 @@ TEST_F(TestCommands, TestAsyncResponse) Protocols::InteractionModel::Status::Success); gAsyncCommandHandle.Release(); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(onSuccessWasCalled && !onFailureWasCalled && statusCheck); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommands, TestFailure) { Clusters::UnitTesting::Commands::TestSimpleArgumentRequest::Type request; - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessWasCalled = false; bool onFailureWasCalled = false; @@ -288,13 +258,13 @@ TEST_F(TestCommands, TestFailure) ScopedChange directive(gCommandResponseDirective, CommandResponseDirective::kSendError); - chip::Controller::InvokeCommandRequest(&mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, + chip::Controller::InvokeCommandRequest(&GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(!onSuccessWasCalled && onFailureWasCalled && statusCheck); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommands, TestMultipleFailures) @@ -305,7 +275,7 @@ TEST_F(TestCommands, TestMultipleFailures) }; FakeRequest request; - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); size_t successCalls = 0; size_t failureCalls = 0; @@ -326,14 +296,13 @@ TEST_F(TestCommands, TestMultipleFailures) ScopedChange directive(gCommandResponseDirective, CommandResponseDirective::kSendMultipleErrors); - Controller::InvokeCommandRequest(&mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, - onFailureCb); + Controller::InvokeCommandRequest(&GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(successCalls, 0u); EXPECT_TRUE(failureCalls == 1 && statusCheck); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommands, TestSuccessNoDataResponseWithClusterStatus) @@ -344,7 +313,7 @@ TEST_F(TestCommands, TestSuccessNoDataResponseWithClusterStatus) }; FakeRequest request; - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessWasCalled = false; bool onFailureWasCalled = false; @@ -366,19 +335,19 @@ TEST_F(TestCommands, TestSuccessNoDataResponseWithClusterStatus) ScopedChange directive(gCommandResponseDirective, CommandResponseDirective::kSendSuccessStatusCodeWithClusterStatus); - chip::Controller::InvokeCommandRequest(&mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, + chip::Controller::InvokeCommandRequest(&GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(onSuccessWasCalled && !onFailureWasCalled && statusCheck); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestCommands, TestFailureWithClusterStatus) { Clusters::UnitTesting::Commands::TestSimpleArgumentRequest::Type request; - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessWasCalled = false; bool onFailureWasCalled = false; @@ -405,13 +374,13 @@ TEST_F(TestCommands, TestFailureWithClusterStatus) ScopedChange directive(gCommandResponseDirective, CommandResponseDirective::kSendErrorWithClusterStatus); - chip::Controller::InvokeCommandRequest(&mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, + chip::Controller::InvokeCommandRequest(&GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(!onSuccessWasCalled && onFailureWasCalled && statusCheck); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } } // namespace diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index 954ff5044418d4..9df501c45e7d78 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -38,8 +38,6 @@ #include #include -using TestContext = chip::Test::AppContext; - using namespace chip; using namespace chip::app; using namespace chip::app::Clusters; @@ -49,40 +47,9 @@ using namespace chip::Test; namespace { -class TestRead : public ::testing::Test, public app::ReadHandler::ApplicationCallback +class TestRead : public chip::Test::AppContext, public app::ReadHandler::ApplicationCallback { -public: - // Performs shared setup for all tests in the test suite - static void SetUpTestSuite() - { - if (mpContext == nullptr) - { - mpContext = new TestContext(); - ASSERT_NE(mpContext, nullptr); - } - mpContext->SetUpTestSuite(); - } - - // Performs shared teardown for all tests in the test suite - static void TearDownTestSuite() - { - mpContext->TearDownTestSuite(); - if (mpContext != nullptr) - { - delete mpContext; - mpContext = nullptr; - } - } - protected: - // Performs setup for each individual test in the test suite - void SetUp() { mpContext->SetUp(); } - - // Performs teardown for each individual test in the test suite - void TearDown() { mpContext->TearDown(); } - - static TestContext * mpContext; - static uint16_t mMaxInterval; CHIP_ERROR OnSubscriptionRequested(app::ReadHandler & aReadHandler, Transport::SecureSession & aSecureSession) @@ -102,16 +69,15 @@ class TestRead : public ::testing::Test, public app::ReadHandler::ApplicationCal // Issue the given number of reads in parallel and wait for them all to // succeed. - static void MultipleReadHelper(TestContext * apCtx, size_t aReadCount); + void MultipleReadHelper(size_t aReadCount); // Helper for MultipleReadHelper that does not spin the event loop, so we // don't end up with nested event loops. - static void MultipleReadHelperInternal(TestContext * apCtx, size_t aReadCount, uint32_t & aNumSuccessCalls, - uint32_t & aNumFailureCalls); + void MultipleReadHelperInternal(size_t aReadCount, uint32_t & aNumSuccessCalls, uint32_t & aNumFailureCalls); // Establish the given number of subscriptions, then issue the given number // of reads in parallel and wait for them all to succeed. - static void SubscribeThenReadHelper(TestContext * apCtx, size_t aSubscribeCount, size_t aReadCount); + void SubscribeThenReadHelper(size_t aSubscribeCount, size_t aReadCount); // Compute the amount of time it would take a subscription with a given // max-interval to time out. @@ -122,8 +88,7 @@ class TestRead : public ::testing::Test, public app::ReadHandler::ApplicationCal bool mAlterSubscriptionIntervals = false; }; -TestContext * TestRead::mpContext = nullptr; -uint16_t TestRead::mMaxInterval = 66; +uint16_t TestRead::mMaxInterval = 66; class MockInteractionModelApp : public chip::app::ClusterStateCache::Callback { @@ -176,7 +141,7 @@ class MockInteractionModelApp : public chip::app::ClusterStateCache::Callback TEST_F(TestRead, TestReadAttributeResponse) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessCbInvoked = false, onFailureCbInvoked = false; ScopedChange directive(gReadResponseDirective, ReadResponseDirective::kSendDataResponse); @@ -205,14 +170,14 @@ TEST_F(TestRead, TestReadAttributeResponse) }; Controller::ReadAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb); + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(onSuccessCbInvoked && !onFailureCbInvoked); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // NOTE: This test must execute before TestReadSubscribeAttributeResponseWithCache or else it will fail on @@ -225,7 +190,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithVersionOnlyCache) MockInteractionModelApp delegate; chip::app::ClusterStateCache cache(delegate, Optional::Missing(), false /*cachedData*/); - chip::app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice()); + chip::app::ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); // // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination // callbacks. @@ -234,7 +199,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithVersionOnlyCache) // read of E2C2A* and E3C2A2. Expect cache E2C2 version { - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); chip::app::AttributePathParams attributePathParams2[2]; attributePathParams2[0].mEndpointId = chip::Test::kMockEndpoint2; @@ -249,7 +214,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithVersionOnlyCache) err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // There are supported 2 global and 3 non-global attributes in E2C2A* and 1 E3C2A2 EXPECT_EQ(delegate.mNumAttributeResponse, 6); EXPECT_FALSE(delegate.mReadError); @@ -286,7 +251,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithVersionOnlyCache) } EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) @@ -305,7 +270,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) eventPathParam.mEventId = 0; } - chip::app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice()); + chip::app::ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mMinIntervalFloorSeconds = 0; readPrepareParams.mMaxIntervalCeilingSeconds = 4; // @@ -321,7 +286,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) { testId++; ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); chip::app::AttributePathParams attributePathParams1[3]; attributePathParams1[0].mEndpointId = chip::Test::kMockEndpoint2; @@ -341,7 +306,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 6); EXPECT_FALSE(delegate.mReadError); Optional version1; @@ -356,7 +321,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) { testId++; ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); chip::app::AttributePathParams attributePathParams1[3]; attributePathParams1[0].mEndpointId = chip::Test::kMockEndpoint2; @@ -376,7 +341,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 3); EXPECT_FALSE(delegate.mReadError); Optional version1; @@ -427,7 +392,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) { testId++; ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); chip::app::AttributePathParams attributePathParams1[3]; attributePathParams1[0].mEndpointId = kInvalidEndpointId; @@ -447,7 +412,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 2); EXPECT_FALSE(delegate.mReadError); Optional version1; @@ -493,7 +458,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) { testId++; ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); chip::app::AttributePathParams attributePathParams2[2]; attributePathParams2[0].mEndpointId = chip::Test::kMockEndpoint2; @@ -508,7 +473,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // There are supported 2 global and 3 non-global attributes in E2C2A* and 1 E3C2A2 EXPECT_EQ(delegate.mNumAttributeResponse, 6); EXPECT_FALSE(delegate.mReadError); @@ -568,7 +533,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) { testId++; ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); chip::app::AttributePathParams attributePathParams1[3]; attributePathParams1[0].mEndpointId = chip::Test::kMockEndpoint2; @@ -588,7 +553,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 1); EXPECT_FALSE(delegate.mReadError); Optional version1; @@ -637,7 +602,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) { testId++; ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); chip::app::AttributePathParams attributePathParams2[2]; attributePathParams2[0].mEndpointId = chip::Test::kMockEndpoint2; @@ -652,7 +617,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 1); EXPECT_FALSE(delegate.mReadError); Optional version1; @@ -714,7 +679,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) { testId++; ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); chip::app::AttributePathParams attributePathParams1[3]; attributePathParams1[0].mEndpointId = chip::Test::kMockEndpoint2; @@ -734,7 +699,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 3); EXPECT_FALSE(delegate.mReadError); Optional version1; @@ -783,7 +748,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) { testId++; ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); chip::app::AttributePathParams attributePathParams1[3]; attributePathParams1[0].mEndpointId = chip::Test::kMockEndpoint2; @@ -803,7 +768,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 3); EXPECT_FALSE(delegate.mReadError); Optional version1; @@ -852,7 +817,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) { testId++; ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); chip::app::AttributePathParams attributePathParams2[2]; attributePathParams2[0].mEndpointId = chip::Test::kMockEndpoint2; @@ -867,7 +832,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 6); EXPECT_FALSE(delegate.mReadError); Optional version1; @@ -927,7 +892,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) { testId++; ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); chip::app::AttributePathParams attributePathParams2[2]; attributePathParams2[0].mEndpointId = chip::Test::kMockEndpoint2; @@ -950,7 +915,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 6); EXPECT_FALSE(delegate.mReadError); Optional version1; @@ -1013,7 +978,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) { testId++; ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); chip::app::AttributePathParams attributePathParams3[3]; @@ -1034,7 +999,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // E1C2A* has 3 attributes and E2C3A* has 5 attributes and E2C2A* has 4 attributes EXPECT_EQ(delegate.mNumAttributeResponse, 12); EXPECT_FALSE(delegate.mReadError); @@ -1120,7 +1085,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) { testId++; ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); chip::app::AttributePathParams attributePathParams3[3]; @@ -1146,7 +1111,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 7); EXPECT_FALSE(delegate.mReadError); Optional version1; @@ -1231,7 +1196,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) { testId++; ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId); - app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), + app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); chip::app::AttributePathParams attributePathParams1[1]; attributePathParams1[0].mEndpointId = chip::Test::kMockEndpoint3; @@ -1242,7 +1207,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 6); EXPECT_FALSE(delegate.mReadError); Optional version1; @@ -1294,12 +1259,12 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) } EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestRead, TestReadEventResponse) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessCbInvoked = false, onFailureCbInvoked = false, onDoneCbInvoked = false; // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's @@ -1318,21 +1283,21 @@ TEST_F(TestRead, TestReadEventResponse) auto onDoneCb = [&onDoneCbInvoked](app::ReadClient * apReadClient) { onDoneCbInvoked = true; }; Controller::ReadEvent( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, onDoneCb); + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, onDoneCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_FALSE(onFailureCbInvoked); EXPECT_TRUE(onDoneCbInvoked); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestRead, TestReadAttributeError) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessCbInvoked = false, onFailureCbInvoked = false; ScopedChange directive(gReadResponseDirective, ReadResponseDirective::kSendDataError); @@ -1351,19 +1316,19 @@ TEST_F(TestRead, TestReadAttributeError) }; Controller::ReadAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb); + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(!onSuccessCbInvoked && onFailureCbInvoked); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestRead, TestReadAttributeTimeout) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessCbInvoked = false, onFailureCbInvoked = false; ScopedChange directive(gReadResponseDirective, ReadResponseDirective::kSendDataError); @@ -1382,21 +1347,21 @@ TEST_F(TestRead, TestReadAttributeTimeout) }; Controller::ReadAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb); + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb); - mpContext->ExpireSessionAliceToBob(); + ExpireSessionAliceToBob(); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 1u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 1u); - mpContext->ExpireSessionBobToAlice(); + ExpireSessionBobToAlice(); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(!onSuccessCbInvoked && onFailureCbInvoked); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u); @@ -1404,10 +1369,10 @@ TEST_F(TestRead, TestReadAttributeTimeout) // Let's put back the sessions so that the next tests (which assume a valid initialized set of sessions) // can function correctly. // - mpContext->CreateSessionAliceToBob(); - mpContext->CreateSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } class TestResubscriptionCallback : public app::ReadClient::Callback @@ -1468,18 +1433,18 @@ class TestResubscriptionCallback : public app::ReadClient::Callback // TEST_F(TestRead, TestResubscribeAttributeTimeout) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); - mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive); + SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive); { TestResubscriptionCallback callback; - app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), callback, + app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), callback, app::ReadClient::InteractionType::Subscribe); callback.SetReadClient(&readClient); - app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice()); + app::ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); // Read full wildcard paths, repeat twice to ensure chunking. app::AttributePathParams attributePathParams[1]; @@ -1499,8 +1464,8 @@ TEST_F(TestRead, TestResubscribeAttributeTimeout) // // Drive servicing IO till we have established a subscription. // - mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), - [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; }); + GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), + [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; }); EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1); EXPECT_EQ(callback.mOnError, 0); EXPECT_EQ(callback.mOnResubscriptionsAttempted, 0); @@ -1515,21 +1480,21 @@ TEST_F(TestRead, TestResubscribeAttributeTimeout) // Disable packet transmission, and drive IO till we have reported a re-subscription attempt. // // - mpContext->GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount; - mpContext->GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)), - [&]() { return callback.mOnResubscriptionsAttempted > 0; }); + GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount; + GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)), + [&]() { return callback.mOnResubscriptionsAttempted > 0; }); EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1); EXPECT_EQ(callback.mLastError, CHIP_ERROR_TIMEOUT); - mpContext->GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToDrop = 0; callback.ClearCounters(); // // Drive servicing IO till we have established a subscription. // - mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), - [&]() { return callback.mOnSubscriptionEstablishedCount == 1; }); + GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), + [&]() { return callback.mOnSubscriptionEstablishedCount == 1; }); EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1); // @@ -1539,10 +1504,10 @@ TEST_F(TestRead, TestResubscribeAttributeTimeout) EXPECT_EQ(callback.mOnDone, 0); } - mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault); + SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault); app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -1551,18 +1516,18 @@ TEST_F(TestRead, TestResubscribeAttributeTimeout) // TEST_F(TestRead, TestSubscribeAttributeTimeout) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); - mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive); + SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive); { TestResubscriptionCallback callback; - app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), callback, + app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), callback, app::ReadClient::InteractionType::Subscribe); callback.SetReadClient(&readClient); - app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice()); + app::ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); app::AttributePathParams attributePathParams[1]; readPrepareParams.mpAttributePathParamsList = attributePathParams; @@ -1583,14 +1548,14 @@ TEST_F(TestRead, TestSubscribeAttributeTimeout) // // Drive servicing IO till we have established a subscription. // - mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), - [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; }); + GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), + [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; }); EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1); // // Request we drop all further messages. // - mpContext->GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount; + GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount; chip::app::ReadHandler * readHandler = app::InteractionModelEngine::GetInstance()->ActiveHandlerAt(0); @@ -1603,8 +1568,8 @@ TEST_F(TestRead, TestSubscribeAttributeTimeout) // by the liveness timer firing once we hit our max-interval plus // retransmit timeouts. // - mpContext->GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)), - [&]() { return callback.mOnError >= 1; }); + GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)), + [&]() { return callback.mOnError >= 1; }); EXPECT_EQ(callback.mOnError, 1); EXPECT_EQ(callback.mLastError, CHIP_ERROR_TIMEOUT); @@ -1612,16 +1577,16 @@ TEST_F(TestRead, TestSubscribeAttributeTimeout) EXPECT_EQ(callback.mOnResubscriptionsAttempted, 0); } - mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault); + SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault); app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); - mpContext->GetLoopback().mNumMessagesToDrop = 0; + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); + GetLoopback().mNumMessagesToDrop = 0; } TEST_F(TestRead, TestReadHandler_MultipleSubscriptions) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); uint32_t numSuccessCalls = 0; uint32_t numSubscriptionEstablishedCalls = 0; @@ -1661,14 +1626,14 @@ TEST_F(TestRead, TestReadHandler_MultipleSubscriptions) for (size_t i = 0; i < (app::InteractionModelEngine::kReadHandlerPoolSize + 1); i++) { EXPECT_EQ(Controller::SubscribeAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 20, + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 20, onSubscriptionEstablishedCb, nullptr, false, true), CHIP_NO_ERROR); } // There are too many messages and the test (gcc_debug, which includes many sanity checks) will be quite slow. Note: report // engine is using ScheduleWork which cannot be handled by DrainAndServiceIO correctly. - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(60), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(60), [&]() { return numSuccessCalls == (app::InteractionModelEngine::kReadHandlerPoolSize + 1) && numSubscriptionEstablishedCalls == (app::InteractionModelEngine::kReadHandlerPoolSize + 1); }); @@ -1680,15 +1645,15 @@ TEST_F(TestRead, TestReadHandler_MultipleSubscriptions) app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); EXPECT_EQ(mNumActiveSubscriptions, 0); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); - mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault); + SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault); app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); } TEST_F(TestRead, TestReadHandler_SubscriptionAppRejection) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); uint32_t numSuccessCalls = 0; uint32_t numFailureCalls = 0; uint32_t numSubscriptionEstablishedCalls = 0; @@ -1724,11 +1689,11 @@ TEST_F(TestRead, TestReadHandler_SubscriptionAppRejection) mEmitSubscriptionError = true; EXPECT_EQ(Controller::SubscribeAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10, + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10, onSubscriptionEstablishedCb, nullptr, false, true), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(numSuccessCalls, 0u); @@ -1742,7 +1707,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionAppRejection) app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); mEmitSubscriptionError = false; @@ -1754,7 +1719,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionAppRejection) // Max interval equal to client-requested min-interval. TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest1) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); uint32_t numSuccessCalls = 0; uint32_t numFailureCalls = 0; uint32_t numSubscriptionEstablishedCalls = 0; @@ -1799,11 +1764,11 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest1) mAlterSubscriptionIntervals = false; EXPECT_EQ(Controller::SubscribeAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 5, 5, + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 5, 5, onSubscriptionEstablishedCb, nullptr, true), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute @@ -1818,7 +1783,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest1) EXPECT_EQ(mNumActiveSubscriptions, 0); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); mAlterSubscriptionIntervals = false; @@ -1829,7 +1794,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest1) // With no server adjustment. TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest2) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); uint32_t numSuccessCalls = 0; uint32_t numFailureCalls = 0; uint32_t numSubscriptionEstablishedCalls = 0; @@ -1874,11 +1839,11 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest2) mAlterSubscriptionIntervals = false; EXPECT_EQ(Controller::SubscribeAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10, + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10, onSubscriptionEstablishedCb, nullptr, true), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute @@ -1893,7 +1858,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest2) EXPECT_EQ(mNumActiveSubscriptions, 0); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); mAlterSubscriptionIntervals = false; @@ -1904,7 +1869,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest2) // With server adjustment to a value greater than client-requested, but less than 60m (allowed). TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest3) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); uint32_t numSuccessCalls = 0; uint32_t numFailureCalls = 0; uint32_t numSubscriptionEstablishedCalls = 0; @@ -1949,11 +1914,11 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest3) mAlterSubscriptionIntervals = true; mMaxInterval = 3000; EXPECT_EQ(Controller::SubscribeAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10, + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10, onSubscriptionEstablishedCb, nullptr, true), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute @@ -1968,7 +1933,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest3) EXPECT_EQ(mNumActiveSubscriptions, 0); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); mAlterSubscriptionIntervals = false; @@ -1981,7 +1946,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest3) // server adjustment to a value greater than client-requested, but greater than 60 (not allowed). TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest4) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); uint32_t numSuccessCalls = 0; uint32_t numFailureCalls = 0; uint32_t numSubscriptionEstablishedCalls = 0; @@ -2017,11 +1982,11 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest4) mAlterSubscriptionIntervals = true; mMaxInterval = 3700; EXPECT_EQ(Controller::SubscribeAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10, + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10, onSubscriptionEstablishedCb, nullptr, true), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute @@ -2035,7 +2000,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest4) EXPECT_EQ(mNumActiveSubscriptions, 0); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); mAlterSubscriptionIntervals = false; @@ -2048,7 +2013,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest4) // With no server adjustment. TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest5) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); uint32_t numSuccessCalls = 0; uint32_t numFailureCalls = 0; uint32_t numSubscriptionEstablishedCalls = 0; @@ -2093,11 +2058,11 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest5) mAlterSubscriptionIntervals = false; EXPECT_EQ(Controller::SubscribeAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 4000, + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 4000, onSubscriptionEstablishedCb, nullptr, true), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute @@ -2112,7 +2077,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest5) EXPECT_EQ(mNumActiveSubscriptions, 0); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); mAlterSubscriptionIntervals = false; @@ -2123,7 +2088,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest5) // With server adjustment to a value lower than 60m. Allowed TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest6) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); uint32_t numSuccessCalls = 0; uint32_t numFailureCalls = 0; uint32_t numSubscriptionEstablishedCalls = 0; @@ -2168,11 +2133,11 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest6) mAlterSubscriptionIntervals = true; mMaxInterval = 3000; EXPECT_EQ(Controller::SubscribeAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 4000, + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 4000, onSubscriptionEstablishedCb, nullptr, true), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute @@ -2187,7 +2152,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest6) EXPECT_EQ(mNumActiveSubscriptions, 0); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); mAlterSubscriptionIntervals = false; @@ -2198,7 +2163,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest6) // With server adjustment to a value larger than 60m, but less than max interval. Allowed TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest7) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); uint32_t numSuccessCalls = 0; uint32_t numFailureCalls = 0; uint32_t numSubscriptionEstablishedCalls = 0; @@ -2242,11 +2207,11 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest7) mAlterSubscriptionIntervals = true; mMaxInterval = 3700; EXPECT_EQ(Controller::SubscribeAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 4000, + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 4000, onSubscriptionEstablishedCb, nullptr, true), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute @@ -2261,7 +2226,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest7) EXPECT_EQ(mNumActiveSubscriptions, 0); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); mAlterSubscriptionIntervals = false; @@ -2274,7 +2239,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest7) // With server adjustment to a value larger than 60m, but larger than max interval. Disallowed TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest8) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); uint32_t numSuccessCalls = 0; uint32_t numFailureCalls = 0; uint32_t numSubscriptionEstablishedCalls = 0; @@ -2309,11 +2274,11 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest8) mAlterSubscriptionIntervals = true; mMaxInterval = 4100; EXPECT_EQ(Controller::SubscribeAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 4000, + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 4000, onSubscriptionEstablishedCb, nullptr, true), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute @@ -2327,7 +2292,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest8) EXPECT_EQ(mNumActiveSubscriptions, 0); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); mAlterSubscriptionIntervals = false; @@ -2337,7 +2302,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest8) // Validate client is not requesting max-interval < min-interval. TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest9) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); uint32_t numSuccessCalls = 0; uint32_t numFailureCalls = 0; uint32_t numSubscriptionEstablishedCalls = 0; @@ -2373,7 +2338,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest9) mAlterSubscriptionIntervals = false; EXPECT_EQ(Controller::SubscribeAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 5, 4, + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 5, 4, onSubscriptionEstablishedCb, nullptr, true), CHIP_ERROR_INVALID_ARGUMENT); @@ -2389,7 +2354,7 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest9) EXPECT_EQ(mNumActiveSubscriptions, 0); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); mAlterSubscriptionIntervals = false; @@ -2401,19 +2366,19 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest9) */ TEST_F(TestRead, TestSubscribe_OnActiveModeNotification) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); - mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive); + SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive); { TestResubscriptionCallback callback; - app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), callback, + app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), callback, app::ReadClient::InteractionType::Subscribe); callback.mScheduleLITResubscribeImmediately = false; callback.SetReadClient(&readClient); - app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice()); + app::ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); // Read full wildcard paths, repeat twice to ensure chunking. app::AttributePathParams attributePathParams[1]; @@ -2434,8 +2399,8 @@ TEST_F(TestRead, TestSubscribe_OnActiveModeNotification) // // Drive servicing IO till we have established a subscription. // - mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), - [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; }); + GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), + [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; }); EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1); EXPECT_EQ(callback.mOnError, 0); EXPECT_EQ(callback.mOnResubscriptionsAttempted, 0); @@ -2451,13 +2416,12 @@ TEST_F(TestRead, TestSubscribe_OnActiveModeNotification) // WakeUp() is called. // // - mpContext->GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount; - mpContext->GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)), - [&]() { return false; }); + GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount; + GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)), [&]() { return false; }); EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1); EXPECT_EQ(callback.mLastError, CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT); - mpContext->GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToDrop = 0; callback.ClearCounters(); app::InteractionModelEngine::GetInstance()->OnActiveModeNotification( ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex())); @@ -2467,8 +2431,8 @@ TEST_F(TestRead, TestSubscribe_OnActiveModeNotification) // // Drive servicing IO till we have established a subscription. // - mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), - [&]() { return callback.mOnSubscriptionEstablishedCount == 1; }); + GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), + [&]() { return callback.mOnSubscriptionEstablishedCount == 1; }); EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1); // @@ -2478,10 +2442,10 @@ TEST_F(TestRead, TestSubscribe_OnActiveModeNotification) EXPECT_EQ(callback.mOnDone, 0); } - mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault); + SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault); app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } /** @@ -2490,21 +2454,21 @@ TEST_F(TestRead, TestSubscribe_OnActiveModeNotification) */ TEST_F(TestRead, TestSubscribe_DynamicLITSubscription) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); - mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive); + SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive); ScopedChange directive(gReadResponseDirective, ReadResponseDirective::kSendDataResponse); ScopedChange isLitIcd(gIsLitIcd, false); { TestResubscriptionCallback callback; - app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), callback, + app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), callback, app::ReadClient::InteractionType::Subscribe); callback.mScheduleLITResubscribeImmediately = false; callback.SetReadClient(&readClient); - app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice()); + app::ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); // Read full wildcard paths, repeat twice to ensure chunking. app::AttributePathParams attributePathParams[1]; @@ -2525,8 +2489,8 @@ TEST_F(TestRead, TestSubscribe_DynamicLITSubscription) // // Drive servicing IO till we have established a subscription. // - mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), - [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; }); + GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), + [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; }); EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1); EXPECT_EQ(callback.mOnError, 0); EXPECT_EQ(callback.mOnResubscriptionsAttempted, 0); @@ -2545,20 +2509,20 @@ TEST_F(TestRead, TestSubscribe_DynamicLITSubscription) // // Even if we set the peer type to LIT before, the report indicates that the peer is a SIT now, it will just bahve as // normal, non-LIT subscriptions. - mpContext->GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount; - mpContext->GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)), - [&]() { return callback.mOnResubscriptionsAttempted != 0; }); + GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount; + GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)), + [&]() { return callback.mOnResubscriptionsAttempted != 0; }); EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1); EXPECT_EQ(callback.mLastError, CHIP_ERROR_TIMEOUT); - mpContext->GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToDrop = 0; callback.ClearCounters(); // // Drive servicing IO till we have established a subscription. // - mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), - [&]() { return callback.mOnSubscriptionEstablishedCount == 1; }); + GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), + [&]() { return callback.mOnSubscriptionEstablishedCount == 1; }); EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1); // @@ -2578,25 +2542,23 @@ TEST_F(TestRead, TestSubscribe_DynamicLITSubscription) app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetDirty(path); } callback.ClearCounters(); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(60), [&]() { - return app::InteractionModelEngine::GetInstance()->GetNumDirtySubscriptions() == 0; - }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(60), + [&]() { return app::InteractionModelEngine::GetInstance()->GetNumDirtySubscriptions() == 0; }); // When we received the update that OperatingMode becomes LIT, we automatically set the inner peer type to LIT ICD. - mpContext->GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount; - mpContext->GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)), - [&]() { return false; }); + GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount; + GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)), [&]() { return false; }); EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1); EXPECT_EQ(callback.mLastError, CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT); - mpContext->GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToDrop = 0; callback.ClearCounters(); } - mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault); + SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault); app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } /** @@ -2605,19 +2567,19 @@ TEST_F(TestRead, TestSubscribe_DynamicLITSubscription) */ TEST_F(TestRead, TestSubscribe_ImmediatelyResubscriptionForLIT) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); - mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive); + SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive); { TestResubscriptionCallback callback; - app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), callback, + app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), callback, app::ReadClient::InteractionType::Subscribe); callback.mScheduleLITResubscribeImmediately = true; callback.SetReadClient(&readClient); - app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice()); + app::ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); // Read full wildcard paths, repeat twice to ensure chunking. app::AttributePathParams attributePathParams[1]; @@ -2638,8 +2600,8 @@ TEST_F(TestRead, TestSubscribe_ImmediatelyResubscriptionForLIT) // // Drive servicing IO till we have established a subscription. // - mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), - [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; }); + GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), + [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; }); EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1); EXPECT_EQ(callback.mOnError, 0); EXPECT_EQ(callback.mOnResubscriptionsAttempted, 0); @@ -2655,20 +2617,20 @@ TEST_F(TestRead, TestSubscribe_ImmediatelyResubscriptionForLIT) // WakeUp() is called. // // - mpContext->GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount; - mpContext->GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)), - [&]() { return callback.mLastError == CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT; }); + GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount; + GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)), + [&]() { return callback.mLastError == CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT; }); EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1); EXPECT_EQ(callback.mLastError, CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT); - mpContext->GetLoopback().mNumMessagesToDrop = 0; + GetLoopback().mNumMessagesToDrop = 0; callback.ClearCounters(); // // Drive servicing IO till we have established a subscription. // - mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), - [&]() { return callback.mOnSubscriptionEstablishedCount == 1; }); + GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), + [&]() { return callback.mOnSubscriptionEstablishedCount == 1; }); EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1); // @@ -2678,10 +2640,10 @@ TEST_F(TestRead, TestSubscribe_ImmediatelyResubscriptionForLIT) EXPECT_EQ(callback.mOnDone, 0); } - mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault); + SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault); app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestRead, TestReadHandler_MultipleReads) @@ -2689,9 +2651,9 @@ TEST_F(TestRead, TestReadHandler_MultipleReads) static_assert(CHIP_IM_MAX_REPORTS_IN_FLIGHT <= app::InteractionModelEngine::kReadHandlerPoolSize, "How can we have more reports in flight than read handlers?"); - MultipleReadHelper(mpContext, CHIP_IM_MAX_REPORTS_IN_FLIGHT); + MultipleReadHelper(CHIP_IM_MAX_REPORTS_IN_FLIGHT); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); } @@ -2702,9 +2664,9 @@ TEST_F(TestRead, TestReadHandler_OneSubscribeMultipleReads) "How can we have more reports in flight than read handlers?"); static_assert(CHIP_IM_MAX_REPORTS_IN_FLIGHT > 1, "We won't do any reads"); - SubscribeThenReadHelper(mpContext, 1, CHIP_IM_MAX_REPORTS_IN_FLIGHT - 1); + SubscribeThenReadHelper(1, CHIP_IM_MAX_REPORTS_IN_FLIGHT - 1); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); } @@ -2715,16 +2677,16 @@ TEST_F(TestRead, TestReadHandler_TwoSubscribesMultipleReads) "How can we have more reports in flight than read handlers?"); static_assert(CHIP_IM_MAX_REPORTS_IN_FLIGHT > 2, "We won't do any reads"); - SubscribeThenReadHelper(mpContext, 2, CHIP_IM_MAX_REPORTS_IN_FLIGHT - 2); + SubscribeThenReadHelper(2, CHIP_IM_MAX_REPORTS_IN_FLIGHT - 2); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); } -void TestRead::SubscribeThenReadHelper(TestContext * apCtx, size_t aSubscribeCount, size_t aReadCount) +void TestRead::SubscribeThenReadHelper(size_t aSubscribeCount, size_t aReadCount) { - auto sessionHandle = apCtx->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); uint32_t numSuccessCalls = 0; uint32_t numSubscriptionEstablishedCalls = 0; @@ -2748,25 +2710,25 @@ void TestRead::SubscribeThenReadHelper(TestContext * apCtx, size_t aSubscribeCou EXPECT_TRUE(false); }; - auto onSubscriptionEstablishedCb = [&numSubscriptionEstablishedCalls, &apCtx, aSubscribeCount, aReadCount, &numReadSuccessCalls, + auto onSubscriptionEstablishedCb = [&numSubscriptionEstablishedCalls, this, aSubscribeCount, aReadCount, &numReadSuccessCalls, &numReadFailureCalls](const app::ReadClient & readClient, chip::SubscriptionId aSubscriptionId) { numSubscriptionEstablishedCalls++; if (numSubscriptionEstablishedCalls == aSubscribeCount) { - MultipleReadHelperInternal(apCtx, aReadCount, numReadSuccessCalls, numReadFailureCalls); + MultipleReadHelperInternal(aReadCount, numReadSuccessCalls, numReadFailureCalls); } }; for (size_t i = 0; i < aSubscribeCount; ++i) { EXPECT_EQ(Controller::SubscribeAttribute( - &apCtx->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10, + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10, onSubscriptionEstablishedCb, nullptr, false, true), CHIP_NO_ERROR); } - apCtx->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(numSuccessCalls, aSubscribeCount); EXPECT_EQ(numSubscriptionEstablishedCalls, aSubscribeCount); @@ -2776,13 +2738,12 @@ void TestRead::SubscribeThenReadHelper(TestContext * apCtx, size_t aSubscribeCou // The guts of MultipleReadHelper which take references to the success/failure // counts to modify and assume the consumer will be spinning the event loop. -void TestRead::MultipleReadHelperInternal(TestContext * apCtx, size_t aReadCount, uint32_t & aNumSuccessCalls, - uint32_t & aNumFailureCalls) +void TestRead::MultipleReadHelperInternal(size_t aReadCount, uint32_t & aNumSuccessCalls, uint32_t & aNumFailureCalls) { EXPECT_EQ(aNumSuccessCalls, 0u); EXPECT_EQ(aNumFailureCalls, 0u); - auto sessionHandle = apCtx->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); ScopedChange directive(gReadResponseDirective, ReadResponseDirective::kSendDataResponse); @@ -2803,19 +2764,19 @@ void TestRead::MultipleReadHelperInternal(TestContext * apCtx, size_t aReadCount }; EXPECT_EQ(Controller::ReadAttribute( - &apCtx->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb), + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb), CHIP_NO_ERROR); } } -void TestRead::MultipleReadHelper(TestContext * apCtx, size_t aReadCount) +void TestRead::MultipleReadHelper(size_t aReadCount) { uint32_t numSuccessCalls = 0; uint32_t numFailureCalls = 0; - MultipleReadHelperInternal(apCtx, aReadCount, numSuccessCalls, numFailureCalls); + MultipleReadHelperInternal(aReadCount, numSuccessCalls, numFailureCalls); - apCtx->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(numSuccessCalls, aReadCount); EXPECT_EQ(numFailureCalls, 0u); @@ -2823,7 +2784,7 @@ void TestRead::MultipleReadHelper(TestContext * apCtx, size_t aReadCount) TEST_F(TestRead, TestReadHandler_MultipleSubscriptionsWithDataVersionFilter) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); uint32_t numSuccessCalls = 0; uint32_t numSubscriptionEstablishedCalls = 0; @@ -2859,14 +2820,14 @@ TEST_F(TestRead, TestReadHandler_MultipleSubscriptionsWithDataVersionFilter) for (size_t i = 0; i < (app::InteractionModelEngine::kReadHandlerPoolSize + 1); i++) { EXPECT_EQ(Controller::SubscribeAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10, + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10, onSubscriptionEstablishedCb, nullptr, false, true, dataVersion), CHIP_NO_ERROR); } // There are too many messages and the test (gcc_debug, which includes many sanity checks) will be quite slow. Note: report // engine is using ScheduleWork which cannot be handled by DrainAndServiceIO correctly. - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(30), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(30), [&]() { return numSubscriptionEstablishedCalls == (app::InteractionModelEngine::kReadHandlerPoolSize + 1) && numSuccessCalls == (app::InteractionModelEngine::kReadHandlerPoolSize + 1); }); @@ -2879,11 +2840,12 @@ TEST_F(TestRead, TestReadHandler_MultipleSubscriptionsWithDataVersionFilter) EXPECT_EQ(numSubscriptionEstablishedCalls, (app::InteractionModelEngine::kReadHandlerPoolSize + 1)); app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestRead, TestReadHandler_DataVersionFiltersTruncated) { + static TestRead * pContext = this; struct : public chip::Test::LoopbackTransportDelegate { size_t requestSize = 0; @@ -2891,13 +2853,13 @@ TEST_F(TestRead, TestReadHandler_DataVersionFiltersTruncated) { // We only care about the messages we (Alice) send to Bob, not the responses. // Assume the first message we see in an iteration is the request. - if (peer == mpContext->GetBobAddress() && requestSize == 0) + if (peer == pContext->GetBobAddress() && requestSize == 0) { requestSize = message->TotalLength(); } } } loopbackDelegate; - mpContext->GetLoopback().SetLoopbackTransportDelegate(&loopbackDelegate); + GetLoopback().SetLoopbackTransportDelegate(&loopbackDelegate); // Note that on the server side, wildcard expansion does not actually work for kTestEndpointId due // to lack of meta-data, but we don't care about the reports we get back in this test. @@ -2919,7 +2881,7 @@ TEST_F(TestRead, TestReadHandler_DataVersionFiltersTruncated) lastRequestSize = loopbackDelegate.requestSize; loopbackDelegate.requestSize = 0; // reset - ReadPrepareParams read(mpContext->GetSessionAliceToBob()); + ReadPrepareParams read(GetSessionAliceToBob()); read.mpAttributePathParamsList = &wildcardPath; read.mAttributePathParamsListSize = 1; read.mpDataVersionFilterList = dataVersionFilters; @@ -2934,14 +2896,14 @@ TEST_F(TestRead, TestReadHandler_DataVersionFiltersTruncated) } readCallback; - ReadClient readClient(app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), readCallback, + ReadClient readClient(app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), readCallback, ReadClient::InteractionType::Read); EXPECT_EQ(readClient.SendRequest(read), CHIP_NO_ERROR); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.done; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.done; }); EXPECT_EQ(readCallback.error, CHIP_NO_ERROR); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); EXPECT_NE(loopbackDelegate.requestSize, 0u); EXPECT_GE(loopbackDelegate.requestSize, lastRequestSize); @@ -2959,12 +2921,12 @@ TEST_F(TestRead, TestReadHandler_DataVersionFiltersTruncated) ADD_FAILURE(); exit: - mpContext->GetLoopback().SetLoopbackTransportDelegate(nullptr); + GetLoopback().SetLoopbackTransportDelegate(nullptr); } TEST_F(TestRead, TestReadHandlerResourceExhaustion_MultipleReads) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); uint32_t numSuccessCalls = 0; uint32_t numFailureCalls = 0; @@ -2989,10 +2951,10 @@ TEST_F(TestRead, TestReadHandlerResourceExhaustion_MultipleReads) app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(true); EXPECT_EQ(Controller::ReadAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb), + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForReads(-1); app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(false); @@ -3001,7 +2963,7 @@ TEST_F(TestRead, TestReadHandlerResourceExhaustion_MultipleReads) EXPECT_EQ(numSuccessCalls, 0u); EXPECT_EQ(numFailureCalls, 1u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestRead, TestReadFabricScopedWithoutFabricFilter) @@ -3016,7 +2978,7 @@ TEST_F(TestRead, TestReadFabricScopedWithoutFabricFilter) * encoder. * - When a fabric filtered read request is received, the response encoder is able to encode the attribute correctly. */ - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessCbInvoked = false, onFailureCbInvoked = false; ScopedChange directive(gReadResponseDirective, ReadResponseDirective::kSendDataResponse); @@ -3039,14 +3001,14 @@ TEST_F(TestRead, TestReadFabricScopedWithoutFabricFilter) }; Controller::ReadAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, false /* fabric filtered */); + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, false /* fabric filtered */); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(onSuccessCbInvoked && !onFailureCbInvoked); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestRead, TestReadFabricScopedWithFabricFilter) @@ -3061,7 +3023,7 @@ TEST_F(TestRead, TestReadFabricScopedWithFabricFilter) * encoder. * - When a fabric filtered read request is received, the response encoder is able to encode the attribute correctly. */ - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessCbInvoked = false, onFailureCbInvoked = false; ScopedChange directive(gReadResponseDirective, ReadResponseDirective::kSendDataResponse); @@ -3093,14 +3055,14 @@ TEST_F(TestRead, TestReadFabricScopedWithFabricFilter) }; Controller::ReadAttribute( - &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, true /* fabric filtered */); + &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, true /* fabric filtered */); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(onSuccessCbInvoked && !onFailureCbInvoked); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } namespace SubscriptionPathQuotaHelpers { @@ -3201,16 +3163,16 @@ void EstablishReadOrSubscriptions(const SessionHandle & sessionHandle, size_t nu TEST_F(TestRead, TestSubscribeAttributeDeniedNotExistPath) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); - mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive); + SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive); { SubscriptionPathQuotaHelpers::TestReadCallback callback; - app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), callback, + app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &GetExchangeManager(), callback, app::ReadClient::InteractionType::Subscribe); - app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice()); + app::ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); app::AttributePathParams attributePathParams[1]; readPrepareParams.mpAttributePathParamsList = attributePathParams; @@ -3226,27 +3188,27 @@ TEST_F(TestRead, TestSubscribeAttributeDeniedNotExistPath) auto err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(callback.mOnError, 1u); EXPECT_EQ(callback.mLastError, CHIP_IM_GLOBAL_STATUS(InvalidAction)); EXPECT_EQ(callback.mOnDone, 1u); } - mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault); + SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault); app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestRead, TestReadHandler_KillOverQuotaSubscriptions) { - // Note: We cannot use mpContext->DrainAndServiceIO() since the perpetual read will make DrainAndServiceIO never return. + // Note: We cannot use DrainAndServiceIO() since the perpetual read will make DrainAndServiceIO never return. using namespace SubscriptionPathQuotaHelpers; - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); const auto kExpectedParallelSubs = - app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric * mpContext->GetFabricTable().FabricCount(); + app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric * GetFabricTable().FabricCount(); const auto kExpectedParallelPaths = kExpectedParallelSubs * app::InteractionModelEngine::kMinSupportedPathsPerSubscription; app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); @@ -3258,13 +3220,13 @@ TEST_F(TestRead, TestReadHandler_KillOverQuotaSubscriptions) TestPerpetualListReadCallback perpetualReadCallback; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, 1, + EstablishReadOrSubscriptions(GetSessionAliceToBob(), 1, 1, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, kPerpetualAttributeid), app::ReadClient::InteractionType::Read, &perpetualReadCallback, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, 1, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, kPerpetualAttributeid), app::ReadClient::InteractionType::Read, &perpetualReadCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read) == 2; }); // Ensure our read transactions are established. @@ -3280,18 +3242,18 @@ TEST_F(TestRead, TestReadHandler_KillOverQuotaSubscriptions) // // Subscription A EstablishReadOrSubscriptions( - mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription + 1, + GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription + 1, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Subscribe, &readCallback, readClients); // Subscription B EstablishReadOrSubscriptions( - mpContext->GetSessionBobToAlice(), kExpectedParallelSubs, app::InteractionModelEngine::kMinSupportedPathsPerSubscription, + GetSessionBobToAlice(), kExpectedParallelSubs, app::InteractionModelEngine::kMinSupportedPathsPerSubscription, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Subscribe, &readCallback, readClients); // There are too many messages and the test (gcc_debug, which includes many sanity checks) will be quite slow. Note: report // engine is using ScheduleWork which cannot be handled by DrainAndServiceIO correctly. - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnSubscriptionEstablishedCount == kExpectedParallelSubs + 1 && readCallback.mAttributeCount == kExpectedParallelSubs * app::InteractionModelEngine::kMinSupportedPathsPerSubscription + @@ -3317,11 +3279,11 @@ TEST_F(TestRead, TestReadHandler_KillOverQuotaSubscriptions) TestReadCallback callback; std::vector> outReadClient; EstablishReadOrSubscriptions( - mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription + 1, + GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription + 1, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Subscribe, &callback, outReadClient); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return callback.mOnError == 1; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return callback.mOnError == 1; }); // Over-sized request after used all paths will receive Paths Exhausted status code. EXPECT_EQ(callback.mOnError, 1u); @@ -3332,13 +3294,13 @@ TEST_F(TestRead, TestReadHandler_KillOverQuotaSubscriptions) // was previously established with more paths than the limit per fabric) { EstablishReadOrSubscriptions( - mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription, + GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Subscribe, &readCallback, readClients); readCallback.ClearCounters(); // Run until the new subscription got setup fully as viewed by the client. - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnSubscriptionEstablishedCount == 1 && readCallback.mAttributeCount == app::InteractionModelEngine::kMinSupportedPathsPerSubscription; }); @@ -3363,9 +3325,8 @@ TEST_F(TestRead, TestReadHandler_KillOverQuotaSubscriptions) readCallback.ClearCounters(); // Run until all subscriptions are clean. - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(60), [&]() { - return app::InteractionModelEngine::GetInstance()->GetNumDirtySubscriptions() == 0; - }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(60), + [&]() { return app::InteractionModelEngine::GetInstance()->GetNumDirtySubscriptions() == 0; }); // Before the above subscription, we have one subscription with kMinSupportedPathsPerSubscription + 1 paths, we should evict // that subscription before evicting any other subscriptions, which will result we used exactly kExpectedParallelPaths and have @@ -3380,19 +3341,19 @@ TEST_F(TestRead, TestReadHandler_KillOverQuotaSubscriptions) // Part 2: Testing per fabric minimas. // Validate we have more than kMinSupportedSubscriptionsPerFabric subscriptions for testing per fabric minimas. EXPECT_GT(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Subscribe, - mpContext->GetAliceFabricIndex()), + GetAliceFabricIndex()), app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric); // The following check will trigger the logic in im to kill the read handlers that use more paths than the limit per fabric. { EstablishReadOrSubscriptions( - mpContext->GetSessionAliceToBob(), app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric, + GetSessionAliceToBob(), app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric, app::InteractionModelEngine::kMinSupportedPathsPerSubscription, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Subscribe, &readCallbackFabric2, readClients); // Run until we have established the subscriptions. - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallbackFabric2.mOnSubscriptionEstablishedCount == app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric && readCallbackFabric2.mAttributeCount == @@ -3420,9 +3381,8 @@ TEST_F(TestRead, TestReadHandler_KillOverQuotaSubscriptions) readCallbackFabric2.ClearCounters(); // Run until all subscriptions are clean. - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(60), [&]() { - return app::InteractionModelEngine::GetInstance()->GetNumDirtySubscriptions() == 0; - }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(60), + [&]() { return app::InteractionModelEngine::GetInstance()->GetNumDirtySubscriptions() == 0; }); // Some subscriptions on fabric 1 should be evicted since fabric 1 is using more resources than the limits. EXPECT_EQ(readCallback.mAttributeCount, @@ -3432,22 +3392,22 @@ TEST_F(TestRead, TestReadHandler_KillOverQuotaSubscriptions) app::InteractionModelEngine::kMinSupportedPathsPerSubscription * app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Subscribe, - mpContext->GetAliceFabricIndex()), + GetAliceFabricIndex()), app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Subscribe, - mpContext->GetBobFabricIndex()), + GetBobFabricIndex()), app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric); // Ensure our read transactions are still alive. EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read), 2u); app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Shutdown all clients readClients.clear(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(false); app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForSubscriptions(-1); app::InteractionModelEngine::GetInstance()->SetPathPoolCapacityForSubscriptions(-1); @@ -3456,10 +3416,10 @@ TEST_F(TestRead, TestReadHandler_KillOverQuotaSubscriptions) TEST_F(TestRead, TestReadHandler_KillOldestSubscriptions) { using namespace SubscriptionPathQuotaHelpers; - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); const auto kExpectedParallelSubs = - app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric * mpContext->GetFabricTable().FabricCount(); + app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric * GetFabricTable().FabricCount(); const auto kExpectedParallelPaths = kExpectedParallelSubs * app::InteractionModelEngine::kMinSupportedPathsPerSubscription; app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); @@ -3473,11 +3433,11 @@ TEST_F(TestRead, TestReadHandler_KillOldestSubscriptions) // This should just use all availbale resources. EstablishReadOrSubscriptions( - mpContext->GetSessionBobToAlice(), kExpectedParallelSubs, app::InteractionModelEngine::kMinSupportedPathsPerSubscription, + GetSessionBobToAlice(), kExpectedParallelSubs, app::InteractionModelEngine::kMinSupportedPathsPerSubscription, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Subscribe, &readCallback, readClients); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(readCallback.mAttributeCount, kExpectedParallelSubs * app::InteractionModelEngine::kMinSupportedPathsPerSubscription); EXPECT_EQ(readCallback.mOnSubscriptionEstablishedCount, kExpectedParallelSubs); @@ -3488,11 +3448,11 @@ TEST_F(TestRead, TestReadHandler_KillOldestSubscriptions) TestReadCallback callback; std::vector> outReadClient; EstablishReadOrSubscriptions( - mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription + 1, + GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription + 1, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Subscribe, &callback, outReadClient); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Over-sized request after used all paths will receive Paths Exhausted status code. EXPECT_EQ(callback.mOnError, 1u); @@ -3502,12 +3462,12 @@ TEST_F(TestRead, TestReadHandler_KillOldestSubscriptions) // The following check will trigger the logic in im to kill the read handlers that uses more paths than the limit per fabric. { EstablishReadOrSubscriptions( - mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription, + GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Subscribe, &readCallback, readClients); readCallback.ClearCounters(); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // This read handler should evict some existing subscriptions for enough space EXPECT_EQ(readCallback.mOnSubscriptionEstablishedCount, 1u); @@ -3524,17 +3484,17 @@ TEST_F(TestRead, TestReadHandler_KillOldestSubscriptions) app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetDirty(path); } readCallback.ClearCounters(); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_LE(readCallback.mAttributeCount, kExpectedParallelPaths); app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); // Shutdown all clients readClients.clear(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(false); app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForSubscriptions(-1); app::InteractionModelEngine::GetInstance()->SetPathPoolCapacityForSubscriptions(-1); @@ -3547,7 +3507,7 @@ struct TestReadHandler_ParallelReads_TestCase_Parameters int MaxFabrics = -1; }; -static void TestReadHandler_ParallelReads_TestCase(TestContext * apContext, +static void TestReadHandler_ParallelReads_TestCase(TestRead * apContext, const TestReadHandler_ParallelReads_TestCase_Parameters & params, std::function body) { @@ -3573,18 +3533,18 @@ static void TestReadHandler_ParallelReads_TestCase(TestContext * apContext, TEST_F(TestRead, TestReadHandler_ParallelReads) { - // Note: We cannot use mpContext->DrainAndServiceIO() except at the end of each test case since the perpetual read transactions - // will never end. Note: We use mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { CONDITION }); and + // Note: We cannot use DrainAndServiceIO() except at the end of each test case since the perpetual read transactions + // will never end. Note: We use GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { CONDITION }); and // EXPECT_EQ( CONDITION ) to ensure the CONDITION is satisfied. using namespace SubscriptionPathQuotaHelpers; using Params = TestReadHandler_ParallelReads_TestCase_Parameters; - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); auto TestCase = [&](const TestReadHandler_ParallelReads_TestCase_Parameters & params, std::function body) { - TestReadHandler_ParallelReads_TestCase(mpContext, params, body); + TestReadHandler_ParallelReads_TestCase(this, params, body); }; // Case 1.1: 2 reads used up the path pool (but not the ReadHandler pool), and one incoming oversized read request => @@ -3601,16 +3561,14 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) TestPerpetualListReadCallback backgroundReadCallback2; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, - app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, - app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0; }); EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0); @@ -3619,11 +3577,11 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) backgroundReadCallback2.ClearCounter(); EstablishReadOrSubscriptions( - mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1, + GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The two subscriptions should still alive EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0); @@ -3646,14 +3604,14 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) TestPerpetualListReadCallback backgroundReadCallback2; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0; }); EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0); @@ -3662,11 +3620,11 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) backgroundReadCallback2.ClearCounter(); EstablishReadOrSubscriptions( - mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1, + GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The two subscriptions should still alive EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0); @@ -3688,26 +3646,24 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) TestPerpetualListReadCallback backgroundReadCallback2; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, - app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, - app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + EstablishReadOrSubscriptions(GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0; }); EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0); EstablishReadOrSubscriptions( - mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1, + GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be accepted EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1); @@ -3716,7 +3672,7 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) // The two subscriptions should still alive backgroundReadCallback1.ClearCounter(); backgroundReadCallback2.ClearCounter(); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0; }); EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0); @@ -3735,16 +3691,14 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) TestPerpetualListReadCallback backgroundReadCallback2; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, - app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, - app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + EstablishReadOrSubscriptions(GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0; }); EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0); @@ -3753,11 +3707,11 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) backgroundReadCallback2.ClearCounter(); EstablishReadOrSubscriptions( - mpContext->GetSessionAliceToBob(), 1, 1, + GetSessionAliceToBob(), 1, 1, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be accepted EXPECT_EQ(readCallback.mAttributeCount, 1u); @@ -3766,7 +3720,7 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) // The two subscriptions should still alive backgroundReadCallback1.ClearCounter(); backgroundReadCallback2.ClearCounter(); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0; }); EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0); @@ -3786,27 +3740,26 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) TestPerpetualListReadCallback backgroundReadCallback; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &readCallbackForOversizedRead, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), - [&]() { return readCallbackForOversizedRead.reportsReceived > 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), + [&]() { return readCallbackForOversizedRead.reportsReceived > 0; }); - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), - [&]() { return backgroundReadCallback.reportsReceived > 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback.reportsReceived > 0; }); EXPECT_TRUE(readCallbackForOversizedRead.reportsReceived > 0 && backgroundReadCallback.reportsReceived > 0); EstablishReadOrSubscriptions( - mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be accepted. EXPECT_EQ(readCallback.mOnError, 0u); @@ -3817,8 +3770,7 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 1u); backgroundReadCallback.ClearCounter(); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), - [&]() { return backgroundReadCallback.reportsReceived > 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback.reportsReceived > 0; }); // We don't check the readCallbackForOversizedRead, since it cannot prove anything -- it can be 0 even when the // oversized read request is alive. We ensure this by checking (1) we have only one active read handler, (2) the one @@ -3842,27 +3794,26 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) TestPerpetualListReadCallback backgroundReadCallback; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), - [&]() { return backgroundReadCallback.reportsReceived > 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback.reportsReceived > 0; }); - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &readCallbackForOversizedRead, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), - [&]() { return readCallbackForOversizedRead.reportsReceived > 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), + [&]() { return readCallbackForOversizedRead.reportsReceived > 0; }); EXPECT_TRUE(readCallbackForOversizedRead.reportsReceived > 0 && backgroundReadCallback.reportsReceived > 0); EstablishReadOrSubscriptions( - mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be accepted. EXPECT_EQ(readCallback.mOnError, 0u); @@ -3873,8 +3824,7 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 1u); backgroundReadCallback.ClearCounter(); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), - [&]() { return backgroundReadCallback.reportsReceived > 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback.reportsReceived > 0; }); // We don't check the readCallbackForOversizedRead, since it cannot prove anything -- it can be 0 even when the // oversized read request is alive. We ensure this by checking (1) we have only one active read handler, (2) the one @@ -3900,25 +3850,25 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) TestPerpetualListReadCallback backgroundReadCallback; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &readCallbackForOversizedRead, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback.reportsReceived > 0 && readCallbackForOversizedRead.reportsReceived > 0; }); EXPECT_TRUE(readCallbackForOversizedRead.reportsReceived > 0 && backgroundReadCallback.reportsReceived > 0); EstablishReadOrSubscriptions( - mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be rejected. EXPECT_NE(readCallback.mOnError, 0u); @@ -3927,7 +3877,7 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) // Ensure the two read transactions are not evicted. backgroundReadCallback.ClearCounter(); readCallbackForOversizedRead.ClearCounter(); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallbackForOversizedRead.reportsReceived > 0 && backgroundReadCallback.reportsReceived > 0; }); EXPECT_TRUE(readCallbackForOversizedRead.reportsReceived > 0 && backgroundReadCallback.reportsReceived > 0); @@ -3948,28 +3898,26 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) TestPerpetualListReadCallback backgroundReadCallback2; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), - [&]() { return backgroundReadCallback1.reportsReceived > 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback1.reportsReceived > 0; }); - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), - [&]() { return backgroundReadCallback2.reportsReceived > 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback2.reportsReceived > 0; }); EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0); backgroundReadCallback1.ClearCounter(); backgroundReadCallback2.ClearCounter(); EstablishReadOrSubscriptions( - mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be rejected. EXPECT_EQ(readCallback.mOnError, 0u); @@ -3982,8 +3930,7 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 1u); // Note: Younger read handler will be evicted. - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), - [&]() { return backgroundReadCallback1.reportsReceived > 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback1.reportsReceived > 0; }); EXPECT_GT(backgroundReadCallback1.reportsReceived, 0); }); @@ -4001,29 +3948,27 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) TestPerpetualListReadCallback backgroundReadCallback2; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), - [&]() { return backgroundReadCallback1.reportsReceived > 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback1.reportsReceived > 0; }); - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), - [&]() { return backgroundReadCallback2.reportsReceived > 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback2.reportsReceived > 0; }); EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0); backgroundReadCallback1.ClearCounter(); backgroundReadCallback2.ClearCounter(); EstablishReadOrSubscriptions( - mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be rejected. EXPECT_EQ(readCallback.mOnError, 0u); @@ -4036,8 +3981,7 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 1u); // Note: Larger read handler will be evicted before evicting the younger one. - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), - [&]() { return backgroundReadCallback2.reportsReceived > 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback2.reportsReceived > 0; }); EXPECT_GT(backgroundReadCallback2.reportsReceived, 0); }); @@ -4058,17 +4002,17 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) TestPerpetualListReadCallback backgroundReadCallback3; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, 1, + EstablishReadOrSubscriptions(GetSessionAliceToBob(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback3, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0 && backgroundReadCallback3.reportsReceived > 0; }); @@ -4076,11 +4020,11 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) backgroundReadCallback3.reportsReceived > 0); EstablishReadOrSubscriptions( - mpContext->GetSessionCharlieToDavid(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + GetSessionCharlieToDavid(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be accepted. EXPECT_EQ(readCallback.mOnError, 0u); @@ -4088,10 +4032,10 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest); // Should evict one read request from Bob fabric for enough resources. EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read, - mpContext->GetAliceFabricIndex()), + GetAliceFabricIndex()), 1u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read, - mpContext->GetBobFabricIndex()), + GetBobFabricIndex()), 1u); }); @@ -4112,17 +4056,17 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) TestPerpetualListReadCallback backgroundReadCallback3; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, 1, + EstablishReadOrSubscriptions(GetSessionAliceToBob(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, 1, + EstablishReadOrSubscriptions(GetSessionAliceToBob(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback3, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0 && backgroundReadCallback3.reportsReceived > 0; }); @@ -4130,11 +4074,11 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) backgroundReadCallback3.reportsReceived > 0); EstablishReadOrSubscriptions( - mpContext->GetSessionCharlieToDavid(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + GetSessionCharlieToDavid(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be accepted. EXPECT_EQ(readCallback.mOnError, 0u); @@ -4142,10 +4086,10 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest); // Should evict one read request from Bob fabric for enough resources. EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read, - mpContext->GetAliceFabricIndex()), + GetAliceFabricIndex()), 1u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read, - mpContext->GetBobFabricIndex()), + GetBobFabricIndex()), 1u); }); @@ -4164,20 +4108,17 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) TestPerpetualListReadCallback backgroundReadCallback3; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, - app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, - app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, - app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + EstablishReadOrSubscriptions(GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback3, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0 && backgroundReadCallback3.reportsReceived > 0; }); @@ -4185,21 +4126,21 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) backgroundReadCallback3.reportsReceived > 0); EstablishReadOrSubscriptions( - mpContext->GetSessionCharlieToDavid(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + GetSessionCharlieToDavid(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be rejected. EXPECT_EQ(readCallback.mOnError, 1u); EXPECT_EQ(readCallback.mLastError, CHIP_IM_GLOBAL_STATUS(Busy)); // Should evict one read request from Bob fabric for enough resources. EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read, - mpContext->GetAliceFabricIndex()), + GetAliceFabricIndex()), 2u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read, - mpContext->GetBobFabricIndex()), + GetBobFabricIndex()), 1u); }); @@ -4217,26 +4158,24 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) TestPerpetualListReadCallback backgroundReadCallback2; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, - app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, - app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + EstablishReadOrSubscriptions(GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0; }); EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0); EstablishReadOrSubscriptions( - mpContext->GetSessionCharlieToDavid(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + GetSessionCharlieToDavid(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be accepted. EXPECT_EQ(readCallback.mOnError, 0u); @@ -4244,10 +4183,10 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest); // No read transactions should be evicted. EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read, - mpContext->GetAliceFabricIndex()), + GetAliceFabricIndex()), 1u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read, - mpContext->GetBobFabricIndex()), + GetBobFabricIndex()), 1u); }); @@ -4265,22 +4204,22 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) TestPerpetualListReadCallback backgroundReadCallback2; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionCharlieToDavid(), 1, 1, + EstablishReadOrSubscriptions(GetSessionCharlieToDavid(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, 1, + EstablishReadOrSubscriptions(GetSessionAliceToBob(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0; }); EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0); EstablishReadOrSubscriptions( - mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be accepted. EXPECT_EQ(readCallback.mOnError, 0u); @@ -4309,23 +4248,23 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) TestPerpetualListReadCallback backgroundReadCallback2; std::vector> readClients; - EstablishReadOrSubscriptions(mpContext->GetSessionCharlieToDavid(), 1, 1, + EstablishReadOrSubscriptions(GetSessionCharlieToDavid(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, + EstablishReadOrSubscriptions(GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0; }); EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0); EstablishReadOrSubscriptions( - mpContext->GetSessionBobToAlice(), 1, 1, + GetSessionBobToAlice(), 1, 1, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be accepted. EXPECT_EQ(readCallback.mOnError, 0u); @@ -4355,15 +4294,15 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) std::vector> readClients; EstablishReadOrSubscriptions( - mpContext->GetSessionCharlieToDavid(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), + GetSessionCharlieToDavid(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallbackForPASESession, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, 1, + EstablishReadOrSubscriptions(GetSessionAliceToBob(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, 1, + EstablishReadOrSubscriptions(GetSessionAliceToBob(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallbackForPASESession.reportsReceived > 0 && backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0; }); @@ -4371,10 +4310,10 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) backgroundReadCallback2.reportsReceived > 0); EstablishReadOrSubscriptions( - mpContext->GetSessionBobToAlice(), 1, 1, + GetSessionBobToAlice(), 1, 1, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be accepted. EXPECT_EQ(readCallback.mOnError, 0u); @@ -4407,14 +4346,14 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) std::vector> readClients; EstablishReadOrSubscriptions( - mpContext->GetSessionCharlieToDavid(), 3, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest - 1, + GetSessionCharlieToDavid(), 3, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest - 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallbackForPASESession, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 3, + EstablishReadOrSubscriptions(GetSessionBobToAlice(), 3, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers( app::ReadHandler::InteractionType::Read) == 6; }); @@ -4424,10 +4363,10 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) // We have to evict one read transaction on PASE session and one read transaction on Alice's fabric. EstablishReadOrSubscriptions( - mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be accepted. EXPECT_EQ(readCallback.mOnError, 0u); @@ -4460,18 +4399,18 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) std::vector> readClients; EstablishReadOrSubscriptions( - mpContext->GetSessionCharlieToDavid(), 2, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest - 1, + GetSessionCharlieToDavid(), 2, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest - 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallbackForPASESession, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, + EstablishReadOrSubscriptions(GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients); - EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, + EstablishReadOrSubscriptions(GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return backgroundReadCallbackForPASESession.reportsReceived > 0 && backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0 && app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read, @@ -4484,10 +4423,10 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) // To handle this read request, we must evict both read transactions from the PASE session. EstablishReadOrSubscriptions( - mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, + GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest, app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id), app::ReadClient::InteractionType::Read, &readCallback, readClients); - mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; }); // The new read request should be accepted. EXPECT_EQ(readCallback.mOnError, 0u); @@ -4504,9 +4443,9 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) }); app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(false); app::InteractionModelEngine::GetInstance()->SetConfigMaxFabrics(-1); app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForReads(-1); @@ -4520,14 +4459,14 @@ TEST_F(TestRead, TestReadHandler_TooManyPaths) { using namespace chip::app; - chip::Messaging::ReliableMessageMgr * rm = mpContext->GetExchangeManager().GetReliableMessageMgr(); + chip::Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); auto * engine = InteractionModelEngine::GetInstance(); engine->SetForceHandlerQuota(true); - ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); // Needs to be larger than our plausible path pool. chip::app::AttributePathParams attributePathParams[sTooLargePathCount]; readPrepareParams.mpAttributePathParamsList = attributePathParams; @@ -4537,13 +4476,13 @@ TEST_F(TestRead, TestReadHandler_TooManyPaths) MockInteractionModelApp delegate; EXPECT_EQ(delegate.mNumAttributeResponse, 0); EXPECT_FALSE(delegate.mReadError); - ReadClient readClient(InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), delegate, + ReadClient readClient(InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate, ReadClient::InteractionType::Read); CHIP_ERROR err = readClient.SendRequest(readPrepareParams); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(delegate.mNumAttributeResponse, 0); EXPECT_TRUE(delegate.mReadError); @@ -4553,7 +4492,7 @@ TEST_F(TestRead, TestReadHandler_TooManyPaths) } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); engine->SetForceHandlerQuota(false); } @@ -4561,7 +4500,7 @@ TEST_F(TestRead, TestReadHandler_TwoParallelReadsSecondTooManyPaths) { using namespace chip::app; - chip::Messaging::ReliableMessageMgr * rm = mpContext->GetExchangeManager().GetReliableMessageMgr(); + chip::Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // Shouldn't have anything in the retransmit table when starting the test. EXPECT_EQ(rm->TestGetCountRetransTable(), 0); @@ -4572,16 +4511,16 @@ TEST_F(TestRead, TestReadHandler_TwoParallelReadsSecondTooManyPaths) MockInteractionModelApp delegate1; EXPECT_EQ(delegate1.mNumAttributeResponse, 0); EXPECT_FALSE(delegate1.mReadError); - ReadClient readClient1(InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), delegate1, + ReadClient readClient1(InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate1, ReadClient::InteractionType::Read); MockInteractionModelApp delegate2; EXPECT_EQ(delegate2.mNumAttributeResponse, 0); EXPECT_FALSE(delegate2.mReadError); - ReadClient readClient2(InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), delegate2, + ReadClient readClient2(InteractionModelEngine::GetInstance(), &GetExchangeManager(), delegate2, ReadClient::InteractionType::Read); - ReadPrepareParams readPrepareParams1(mpContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams1(GetSessionBobToAlice()); // Read full wildcard paths, repeat twice to ensure chunking. chip::app::AttributePathParams attributePathParams1[2]; readPrepareParams1.mpAttributePathParamsList = attributePathParams1; @@ -4590,7 +4529,7 @@ TEST_F(TestRead, TestReadHandler_TwoParallelReadsSecondTooManyPaths) CHIP_ERROR err = readClient1.SendRequest(readPrepareParams1); EXPECT_EQ(err, CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams2(mpContext->GetSessionBobToAlice()); + ReadPrepareParams readPrepareParams2(GetSessionBobToAlice()); // Read full wildcard paths, repeat twice to ensure chunking. chip::app::AttributePathParams attributePathParams2[sTooLargePathCount]; readPrepareParams2.mpAttributePathParamsList = attributePathParams2; @@ -4599,7 +4538,7 @@ TEST_F(TestRead, TestReadHandler_TwoParallelReadsSecondTooManyPaths) err = readClient2.SendRequest(readPrepareParams2); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_NE(delegate1.mNumAttributeResponse, 0); EXPECT_FALSE(delegate1.mReadError); @@ -4612,13 +4551,13 @@ TEST_F(TestRead, TestReadHandler_TwoParallelReadsSecondTooManyPaths) } EXPECT_EQ(engine->GetNumActiveReadClients(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); engine->SetForceHandlerQuota(false); } TEST_F(TestRead, TestReadAttribute_ManyDataValues) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); size_t successCalls = 0; size_t failureCalls = 0; @@ -4637,21 +4576,21 @@ TEST_F(TestRead, TestReadAttribute_ManyDataValues) // not safe to do so. auto onFailureCb = [&failureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) { ++failureCalls; }; - Controller::ReadAttribute(&mpContext->GetExchangeManager(), sessionHandle, + Controller::ReadAttribute(&GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(successCalls, 1u); EXPECT_EQ(failureCalls, 0u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestRead, TestReadAttribute_ManyDataValuesWrongPath) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); size_t successCalls = 0; size_t failureCalls = 0; @@ -4670,21 +4609,21 @@ TEST_F(TestRead, TestReadAttribute_ManyDataValuesWrongPath) // not safe to do so. auto onFailureCb = [&failureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) { ++failureCalls; }; - Controller::ReadAttribute(&mpContext->GetExchangeManager(), sessionHandle, + Controller::ReadAttribute(&GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(successCalls, 0u); EXPECT_EQ(failureCalls, 1u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestRead, TestReadAttribute_ManyErrors) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); size_t successCalls = 0; size_t failureCalls = 0; @@ -4703,16 +4642,16 @@ TEST_F(TestRead, TestReadAttribute_ManyErrors) // not safe to do so. auto onFailureCb = [&failureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) { ++failureCalls; }; - Controller::ReadAttribute(&mpContext->GetExchangeManager(), sessionHandle, + Controller::ReadAttribute(&GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(successCalls, 0u); EXPECT_EQ(failureCalls, 1u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -4728,7 +4667,7 @@ TEST_F(TestRead, TestReadHandler_KeepSubscriptionTest) TestReadCallback readCallback; app::AttributePathParams pathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id); - app::ReadPrepareParams readParam(mpContext->GetSessionAliceToBob()); + app::ReadPrepareParams readParam(GetSessionAliceToBob()); readParam.mpAttributePathParamsList = &pathParams; readParam.mAttributePathParamsListSize = 1; readParam.mMaxIntervalCeilingSeconds = 1; @@ -4739,7 +4678,7 @@ TEST_F(TestRead, TestReadHandler_KeepSubscriptionTest) app::ReadClient::InteractionType::Subscribe); EXPECT_EQ(readClient->SendRequest(readParam), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 1u); @@ -4751,12 +4690,12 @@ TEST_F(TestRead, TestReadHandler_KeepSubscriptionTest) app::ReadClient::InteractionType::Subscribe); EXPECT_EQ(readClient->SendRequest(readParam), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u); EXPECT_NE(readCallback.mOnError, 0u); app::InteractionModelEngine::GetInstance()->ShutdownActiveReads(); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); } System::Clock::Timeout TestRead::ComputeSubscriptionTimeout(System::Clock::Seconds16 aMaxInterval) diff --git a/src/controller/tests/data_model/TestWrite.cpp b/src/controller/tests/data_model/TestWrite.cpp index 8f0d96f7667507..03d100ab33dabb 100644 --- a/src/controller/tests/data_model/TestWrite.cpp +++ b/src/controller/tests/data_model/TestWrite.cpp @@ -33,8 +33,6 @@ #include #include -using TestContext = chip::Test::AppContext; - using namespace chip; using namespace chip::app; using namespace chip::app::Clusters; @@ -84,31 +82,9 @@ class SingleWriteCallback : public WriteClient::Callback StatusIB mPathStatus; }; -class TestWrite : public ::testing::Test +class TestWrite : public chip::Test::AppContext { public: - // Performs shared setup for all tests in the test suite - static void SetUpTestSuite() - { - if (mpContext == nullptr) - { - mpContext = new TestContext(); - ASSERT_NE(mpContext, nullptr); - } - mpContext->SetUpTestSuite(); - } - - // Performs shared teardown for all tests in the test suite - static void TearDownTestSuite() - { - mpContext->TearDownTestSuite(); - if (mpContext != nullptr) - { - delete mpContext; - mpContext = nullptr; - } - } - void ResetCallback() { mSingleWriteCallback.reset(); } void PrepareWriteCallback(ConcreteAttributePath path) { mSingleWriteCallback = std::make_unique(path); } @@ -116,22 +92,12 @@ class TestWrite : public ::testing::Test SingleWriteCallback * GetWriteCallback() { return mSingleWriteCallback.get(); } protected: - // Performs setup for each individual test in the test suite - void SetUp() { mpContext->SetUp(); } - - // Performs teardown for each individual test in the test suite - void TearDown() { mpContext->TearDown(); } - - static TestContext * mpContext; - std::unique_ptr mSingleWriteCallback; }; -TestContext * TestWrite::mpContext = nullptr; - TEST_F(TestWrite, TestDataResponse) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessCbInvoked = false, onFailureCbInvoked = false; Clusters::UnitTesting::Structs::TestListStructOctet::Type valueBuf[4]; Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo::Type value; @@ -160,16 +126,16 @@ TEST_F(TestWrite, TestDataResponse) chip::Controller::WriteAttribute( sessionHandle, kTestEndpointId, value, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(onSuccessCbInvoked && !onFailureCbInvoked); EXPECT_EQ(chip::app::InteractionModelEngine::GetInstance()->GetNumActiveWriteHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestWrite, TestDataResponseWithAcceptedDataVersion) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessCbInvoked = false, onFailureCbInvoked = false; Clusters::UnitTesting::Structs::TestListStructOctet::Type valueBuf[4]; Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo::Type value; @@ -200,16 +166,16 @@ TEST_F(TestWrite, TestDataResponseWithAcceptedDataVersion) chip::Controller::WriteAttribute( sessionHandle, kTestEndpointId, value, onSuccessCb, onFailureCb, nullptr, dataVersion); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(onSuccessCbInvoked && !onFailureCbInvoked); EXPECT_EQ(chip::app::InteractionModelEngine::GetInstance()->GetNumActiveWriteHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestWrite, TestDataResponseWithRejectedDataVersion) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessCbInvoked = false, onFailureCbInvoked = false; Clusters::UnitTesting::Structs::TestListStructOctet::Type valueBuf[4]; Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo::Type value; @@ -239,16 +205,16 @@ TEST_F(TestWrite, TestDataResponseWithRejectedDataVersion) chip::Controller::WriteAttribute( sessionHandle, kTestEndpointId, value, onSuccessCb, onFailureCb, nullptr, dataVersion); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(!onSuccessCbInvoked && onFailureCbInvoked); EXPECT_EQ(chip::app::InteractionModelEngine::GetInstance()->GetNumActiveWriteHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestWrite, TestAttributeError) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessCbInvoked = false, onFailureCbInvoked = false; Attributes::ListStructOctetString::TypeInfo::Type value; Structs::TestListStructOctet::Type valueBuf[4]; @@ -278,16 +244,16 @@ TEST_F(TestWrite, TestAttributeError) Controller::WriteAttribute(sessionHandle, kTestEndpointId, value, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(!onSuccessCbInvoked && onFailureCbInvoked); EXPECT_EQ(InteractionModelEngine::GetInstance()->GetNumActiveWriteHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestWrite, TestFabricScopedAttributeWithoutFabricIndex) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); bool onSuccessCbInvoked = false, onFailureCbInvoked = false; Clusters::UnitTesting::Structs::TestFabricScoped::Type valueBuf[4]; Clusters::UnitTesting::Attributes::ListFabricScoped::TypeInfo::Type value; @@ -315,16 +281,16 @@ TEST_F(TestWrite, TestFabricScopedAttributeWithoutFabricIndex) chip::Controller::WriteAttribute( sessionHandle, kTestEndpointId, value, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(!onSuccessCbInvoked && onFailureCbInvoked); EXPECT_EQ(chip::app::InteractionModelEngine::GetInstance()->GetNumActiveWriteHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestWrite, TestMultipleSuccessResponses) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); size_t successCalls = 0; size_t failureCalls = 0; @@ -341,17 +307,17 @@ TEST_F(TestWrite, TestMultipleSuccessResponses) chip::Controller::WriteAttribute(sessionHandle, kTestEndpointId, true, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(successCalls, 1u); EXPECT_EQ(failureCalls, 0u); EXPECT_EQ(chip::app::InteractionModelEngine::GetInstance()->GetNumActiveWriteHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestWrite, TestMultipleFailureResponses) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); size_t successCalls = 0; size_t failureCalls = 0; @@ -368,17 +334,17 @@ TEST_F(TestWrite, TestMultipleFailureResponses) chip::Controller::WriteAttribute(sessionHandle, kTestEndpointId, true, onSuccessCb, onFailureCb); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_EQ(successCalls, 0u); EXPECT_EQ(failureCalls, 1u); EXPECT_EQ(chip::app::InteractionModelEngine::GetInstance()->GetNumActiveWriteHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } TEST_F(TestWrite, TestWriteClusterSpecificStatuses) { - auto sessionHandle = mpContext->GetSessionBobToAlice(); + auto sessionHandle = GetSessionBobToAlice(); // Cluster-specific success code case { @@ -390,14 +356,14 @@ TEST_F(TestWrite, TestWriteClusterSpecificStatuses) SingleWriteCallback * writeCb = this->GetWriteCallback(); - WriteClient writeClient(&mpContext->GetExchangeManager(), this->GetWriteCallback(), Optional::Missing()); + WriteClient writeClient(&GetExchangeManager(), this->GetWriteCallback(), Optional::Missing()); AttributePathParams attributePath{ kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int8u::Id }; constexpr uint8_t attributeValue = 1u; ASSERT_EQ(writeClient.EncodeAttribute(attributePath, attributeValue), CHIP_NO_ERROR); ASSERT_EQ(writeClient.SendWriteRequest(sessionHandle), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(writeCb->WasDone()); EXPECT_TRUE(writeCb->PathWasResponded()); @@ -409,7 +375,7 @@ TEST_F(TestWrite, TestWriteClusterSpecificStatuses) EXPECT_EQ(pathStatus.mClusterStatus.Value(), kExampleClusterSpecificSuccess); EXPECT_EQ(chip::app::InteractionModelEngine::GetInstance()->GetNumActiveWriteHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // Cluster-specific failure code case @@ -422,7 +388,7 @@ TEST_F(TestWrite, TestWriteClusterSpecificStatuses) SingleWriteCallback * writeCb = this->GetWriteCallback(); - WriteClient writeClient(&mpContext->GetExchangeManager(), this->GetWriteCallback(), Optional::Missing()); + WriteClient writeClient(&GetExchangeManager(), this->GetWriteCallback(), Optional::Missing()); AttributePathParams attributePath{ kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int8u::Id }; @@ -430,7 +396,7 @@ TEST_F(TestWrite, TestWriteClusterSpecificStatuses) ASSERT_EQ(writeClient.EncodeAttribute(attributePath, attributeValue), CHIP_NO_ERROR); ASSERT_EQ(writeClient.SendWriteRequest(sessionHandle), CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); EXPECT_TRUE(writeCb->WasDone()); EXPECT_TRUE(writeCb->PathWasResponded()); @@ -442,7 +408,7 @@ TEST_F(TestWrite, TestWriteClusterSpecificStatuses) EXPECT_EQ(pathStatus.mClusterStatus.Value(), kExampleClusterSpecificFailure); EXPECT_EQ(chip::app::InteractionModelEngine::GetInstance()->GetNumActiveWriteHandlers(), 0u); - EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } } diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 331d61129b9daf..da40f1ca24d9ac 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -2290,8 +2290,12 @@ + (MTRAttributeRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)end - (BOOL)isEqualToAttributeRequestPath:(MTRAttributeRequestPath *)path { - return [_endpoint isEqualToNumber:path.endpoint] && [_cluster isEqualToNumber:path.cluster] && - [_attribute isEqualToNumber:path.attribute]; + if (!path) + return NO; + + return (path.endpoint && [_endpoint isEqualToNumber:path.endpoint]) + && (path.cluster && [_cluster isEqualToNumber:path.cluster]) + && (path.attribute && [_attribute isEqualToNumber:path.attribute]); } - (BOOL)isEqual:(id)object @@ -2362,8 +2366,12 @@ + (MTREventRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)endpoin - (BOOL)isEqualToEventRequestPath:(MTREventRequestPath *)path { - return - [_endpoint isEqualToNumber:path.endpoint] && [_cluster isEqualToNumber:path.cluster] && [_event isEqualToNumber:path.event]; + if (!path) + return NO; + + return (path.endpoint && [_endpoint isEqualToNumber:path.endpoint]) + && (path.cluster && [_cluster isEqualToNumber:path.cluster]) + && (path.event && [_event isEqualToNumber:path.event]); } - (BOOL)isEqual:(id)object @@ -2432,7 +2440,11 @@ ConcreteClusterPath path(static_cast([endpointID unsignedShort - (BOOL)isEqualToClusterPath:(MTRClusterPath *)clusterPath { - return [_endpoint isEqualToNumber:clusterPath.endpoint] && [_cluster isEqualToNumber:clusterPath.cluster]; + if (!clusterPath) + return NO; + + return (clusterPath.endpoint && [_endpoint isEqualToNumber:clusterPath.endpoint]) + && (clusterPath.cluster && [_cluster isEqualToNumber:clusterPath.cluster]); } - (BOOL)isEqual:(id)object @@ -2520,7 +2532,10 @@ ConcreteDataAttributePath path(static_cast([endpointID unsigne - (BOOL)isEqualToAttributePath:(MTRAttributePath *)attributePath { - return [self isEqualToClusterPath:attributePath] && [_attribute isEqualToNumber:attributePath.attribute]; + if (!attributePath) + return NO; + + return [self isEqualToClusterPath:attributePath] && attributePath.attribute && [_attribute isEqualToNumber:attributePath.attribute]; } - (BOOL)isEqual:(id)object @@ -2613,7 +2628,10 @@ ConcreteEventPath path(static_cast([endpointID unsignedShortVa - (BOOL)isEqualToEventPath:(MTREventPath *)eventPath { - return [self isEqualToClusterPath:eventPath] && [_event isEqualToNumber:eventPath.event]; + if (!eventPath) + return NO; + + return [self isEqualToClusterPath:eventPath] && eventPath.event && [_event isEqualToNumber:eventPath.event]; } - (BOOL)isEqual:(id)object @@ -2703,7 +2721,10 @@ ConcreteCommandPath path(static_cast([endpointID unsignedShort - (BOOL)isEqualToCommandPath:(MTRCommandPath *)commandPath { - return [self isEqualToClusterPath:commandPath] && [_command isEqualToNumber:commandPath.command]; + if (!commandPath) + return NO; + + return [self isEqualToClusterPath:commandPath] && commandPath.command && [_command isEqualToNumber:commandPath.command]; } - (BOOL)isEqual:(id)object diff --git a/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.h b/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.h index ebcf3aae949433..9edd153fd2410c 100644 --- a/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.h +++ b/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -93,6 +94,12 @@ class MTRBaseSubscriptionCallback : public chip::app::ClusterStateCache::Callbac chip::app::BufferedReadCallback & GetBufferedCallback() { return mBufferedReadAdapter; } + // Methods to clear state from our cluster state cache. Must be called on + // the Matter queue. + void ClearCachedAttributeState(chip::EndpointId aEndpoint); + void ClearCachedAttributeState(const chip::app::ConcreteClusterPath & aCluster); + void ClearCachedAttributeState(const chip::app::ConcreteAttributePath & aAttribute); + // We need to exist to get a ReadClient, so can't take this as a constructor argument. void AdoptReadClient(std::unique_ptr aReadClient) { mReadClient = std::move(aReadClient); } void AdoptClusterStateCache(std::unique_ptr aClusterStateCache) diff --git a/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.mm b/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.mm index ca91aed5016126..4d91c76a385a9f 100644 --- a/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.mm +++ b/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.mm @@ -201,3 +201,27 @@ }); } } + +void MTRBaseSubscriptionCallback::ClearCachedAttributeState(EndpointId aEndpoint) +{ + assertChipStackLockedByCurrentThread(); + if (mClusterStateCache) { + mClusterStateCache->ClearAttributes(aEndpoint); + } +} + +void MTRBaseSubscriptionCallback::ClearCachedAttributeState(const ConcreteClusterPath & aCluster) +{ + assertChipStackLockedByCurrentThread(); + if (mClusterStateCache) { + mClusterStateCache->ClearAttributes(aCluster); + } +} + +void MTRBaseSubscriptionCallback::ClearCachedAttributeState(const ConcreteAttributePath & aAttribute) +{ + assertChipStackLockedByCurrentThread(); + if (mClusterStateCache) { + mClusterStateCache->ClearAttribute(aAttribute); + } +} diff --git a/src/darwin/Framework/CHIP/MTRDevice.h b/src/darwin/Framework/CHIP/MTRDevice.h index a8098a7174572e..1c31cbc26a661b 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.h +++ b/src/darwin/Framework/CHIP/MTRDevice.h @@ -114,7 +114,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * * The delegate will be called on the provided queue, for attribute reports, event reports, and device state changes. */ -- (void)setDelegate:(id)delegate queue:(dispatch_queue_t)queue MTR_NEWLY_DEPRECATED("Please use addDelegate:queue:interestedPaths:"); +- (void)setDelegate:(id)delegate queue:(dispatch_queue_t)queue MTR_DEPRECATED("Please use addDelegate:queue:interestedPaths:", ios(16.1, 18.0), macos(13.0, 15.0), watchos(9.1, 11.0), tvos(16.1, 18.0)); /** * Adds a delegate to receive asynchronous callbacks about the device. @@ -123,7 +123,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * * MTRDevice holds a weak reference to the delegate object. */ -- (void)addDelegate:(id)delegate queue:(dispatch_queue_t)queue MTR_NEWLY_AVAILABLE; +- (void)addDelegate:(id)delegate queue:(dispatch_queue_t)queue MTR_AVAILABLE(ios(18.0), macos(15.0), watchos(11.0), tvos(18.0)); /** * Adds a delegate to receive asynchronous callbacks about the device, and limit attribute and/or event reports to a specific set of paths. @@ -138,12 +138,12 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * * MTRDevice holds a weak reference to the delegate object. */ -- (void)addDelegate:(id)delegate queue:(dispatch_queue_t)queue interestedPathsForAttributes:(NSArray * _Nullable)interestedPathsForAttributes interestedPathsForEvents:(NSArray * _Nullable)interestedPathsForEvents MTR_NEWLY_AVAILABLE; +- (void)addDelegate:(id)delegate queue:(dispatch_queue_t)queue interestedPathsForAttributes:(NSArray * _Nullable)interestedPathsForAttributes interestedPathsForEvents:(NSArray * _Nullable)interestedPathsForEvents MTR_AVAILABLE(ios(18.0), macos(15.0), watchos(11.0), tvos(18.0)); /** * Removes the delegate from receiving callbacks about the device. */ -- (void)removeDelegate:(id)delegate MTR_NEWLY_AVAILABLE; +- (void)removeDelegate:(id)delegate MTR_AVAILABLE(ios(18.0), macos(15.0), watchos(11.0), tvos(18.0)); /** * Read attribute in a designated attribute path. If there is no value available diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index 89db49f077cdca..eb490bdbe0d37c 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -60,6 +60,9 @@ #define kSecondsToWaitBeforeMarkingUnreachableAfterSettingUpSubscription 10 +// Disabling pending crashes +#define ENABLE_CONNECTIVITY_MONITORING 0 + // Consider moving utility classes to their own file #pragma mark - Utility Classes @@ -333,7 +336,11 @@ - (id)copyWithZone:(NSZone *)zone - (BOOL)isEqualToClusterData:(MTRDeviceClusterData *)otherClusterData { - return [_dataVersion isEqual:otherClusterData.dataVersion] && [_attributes isEqual:otherClusterData.attributes]; + if (!otherClusterData) + return NO; + + return (otherClusterData.dataVersion && [_dataVersion isEqual:otherClusterData.dataVersion]) + && (otherClusterData.attributes && [_attributes isEqual:otherClusterData.attributes]); } - (BOOL)isEqual:(id)object @@ -536,6 +543,9 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:_systemTimeChangeObserverToken]; + + // TODO: retain cycle and clean up https://github.com/project-chip/connectedhomeip/issues/34267 + MTR_LOG("MTRDevice dealloc: %p", self); } - (NSString *)description @@ -796,7 +806,7 @@ - (void)addDelegate:(id)delegate queue:(dispatch_queue_t)queu [self _addDelegate:delegate queue:queue interestedPathsForAttributes:nil interestedPathsForEvents:nil]; } -- (void)addDelegate:(id)delegate queue:(dispatch_queue_t)queue interestedPathsForAttributes:(NSArray * _Nullable)interestedPathsForAttributes interestedPathsForEvents:(NSArray * _Nullable)interestedPathsForEvents MTR_NEWLY_AVAILABLE; +- (void)addDelegate:(id)delegate queue:(dispatch_queue_t)queue interestedPathsForAttributes:(NSArray * _Nullable)interestedPathsForAttributes interestedPathsForEvents:(NSArray * _Nullable)interestedPathsForEvents { MTR_LOG("%@ addDelegate %@ with interested attribute paths %@ event paths %@", self, delegate, interestedPathsForAttributes, interestedPathsForEvents); [self _addDelegate:delegate queue:queue interestedPathsForAttributes:interestedPathsForAttributes interestedPathsForEvents:interestedPathsForEvents]; @@ -841,11 +851,13 @@ - (void)_addDelegate:(id)delegate queue:(dispatch_queue_t)que #endif if (shouldSetUpSubscription) { + MTR_LOG("%@ - starting subscription setup", self); // Record the time of first addDelegate call that triggers initial subscribe, and do not reset this value on subsequent addDelegate calls if (!_initialSubscribeStart) { _initialSubscribeStart = [NSDate now]; } if ([self _deviceUsesThread]) { + MTR_LOG(" => %@ - device is a thread device, scheduling in pool", self); [self _scheduleSubscriptionPoolWork:^{ std::lock_guard lock(self->_lock); [self _setupSubscriptionWithReason:@"delegate is set and scheduled subscription is happening"]; @@ -1298,7 +1310,7 @@ - (void)_scheduleSubscriptionPoolWork:(dispatch_block_t)workBlock inNanoseconds: // Sanity check we are not scheduling for this device multiple times in the pool if (_subscriptionPoolWorkCompletionBlock) { - MTR_LOG_ERROR("%@ already scheduled in subscription pool for this device - ignoring: %@", self, description); + MTR_LOG("%@ already scheduled in subscription pool for this device - ignoring: %@", self, description); return; } @@ -1307,6 +1319,7 @@ - (void)_scheduleSubscriptionPoolWork:(dispatch_block_t)workBlock inNanoseconds: // In the case where a resubscription triggering event happened and already established, running the work block should result in a no-op MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.queue]; [workItem setReadyHandler:^(id _Nonnull context, NSInteger retryCount, MTRAsyncWorkCompletionBlock _Nonnull completion) { + MTR_LOG("%@ - work item is ready to attempt pooled subscription", self); os_unfair_lock_lock(&self->_lock); #ifdef DEBUG [self _callDelegatesWithBlock:^(id testDelegate) { @@ -1332,6 +1345,7 @@ - (void)_scheduleSubscriptionPoolWork:(dispatch_block_t)workBlock inNanoseconds: workBlock(); }]; [self->_deviceController.concurrentSubscriptionPool enqueueWorkItem:workItem description:description]; + MTR_LOG("%@ - enqueued in the subscription pool", self); }); } @@ -1381,7 +1395,7 @@ - (void)_handleResubscriptionNeededWithDelay:(NSNumber *)resubscriptionDelayMs dispatch_after(dispatch_time(DISPATCH_TIME_NOW, resubscriptionDelayNs), self.queue, resubscriptionBlock); } - // Set up connectivity monitoring in case network routability changes for the positive, to accellerate resubscription + // Set up connectivity monitoring in case network routability changes for the positive, to accelerate resubscription [self _setupConnectivityMonitoring]; } @@ -1389,7 +1403,7 @@ - (void)_handleSubscriptionReset:(NSNumber * _Nullable)retryDelay { std::lock_guard lock(_lock); - // If we are here, then either we failed to establish initil CASE, or we + // If we are here, then either we failed to establish initial CASE, or we // failed to send the initial SubscribeRequest message, or our ReadClient // has given up completely. Those all count as "we have tried and failed to // subscribe". @@ -2253,6 +2267,7 @@ - (void)_createDataVersionFilterListFromDictionary:(NSDictionary_lock); + if (self->_currentSubscriptionCallback) { + self->_currentSubscriptionCallback->ClearCachedAttributeState(static_cast(endpoint.unsignedLongLongValue)); + } + } errorHandler:nil]; } } @@ -3449,6 +3472,17 @@ - (void)_pruneClustersIn:(MTRDeviceDataValueDictionary)previousServerListValue } } [self _removeClusters:clusterPathsToRemove doRemoveFromDataStore:YES]; + + [_deviceController asyncDispatchToMatterQueue:^{ + std::lock_guard lock(self->_lock); + if (self->_currentSubscriptionCallback) { + for (NSNumber * cluster in toBeRemovedClusters) { + ConcreteClusterPath clusterPath(static_cast(endpointID.unsignedLongLongValue), + static_cast(cluster.unsignedLongLongValue)); + self->_currentSubscriptionCallback->ClearCachedAttributeState(clusterPath); + } + } + } errorHandler:nil]; } - (void)_pruneAttributesIn:(MTRDeviceDataValueDictionary)previousAttributeListValue @@ -3462,6 +3496,18 @@ - (void)_pruneAttributesIn:(MTRDeviceDataValueDictionary)previousAttributeListVa [toBeRemovedAttributes minusSet:attributesStillInCluster]; [self _removeAttributes:toBeRemovedAttributes fromCluster:clusterPath]; + + [_deviceController asyncDispatchToMatterQueue:^{ + std::lock_guard lock(self->_lock); + if (self->_currentSubscriptionCallback) { + for (NSNumber * attribute in toBeRemovedAttributes) { + ConcreteAttributePath attributePath(static_cast(clusterPath.endpoint.unsignedLongLongValue), + static_cast(clusterPath.cluster.unsignedLongLongValue), + static_cast(attribute.unsignedLongLongValue)); + self->_currentSubscriptionCallback->ClearCachedAttributeState(attributePath); + } + } + } errorHandler:nil]; } - (void)_pruneStoredDataForPath:(MTRAttributePath *)attributePath diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index cea281551384d0..0f263d756c5e7b 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -295,6 +295,7 @@ - (void)shutdown return; } + MTR_LOG("Shutting down MTRDeviceController: %@", self); [self cleanupAfterStartup]; } @@ -306,6 +307,7 @@ - (void)cleanupAfterStartup // do the secure session shutdowns. Since we don't want to hold the lock // while calling out into arbitrary invalidation code, snapshot the list of // devices before we start invalidating. + MTR_LOG("cleanupAfterStartup MTRDeviceController: %@", self); os_unfair_lock_lock(&_deviceMapLock); NSEnumerator * devices = [_nodeIDToDeviceMap objectEnumerator]; [_nodeIDToDeviceMap removeAllObjects]; @@ -323,6 +325,7 @@ - (void)cleanupAfterStartup // in a very specific way that only MTRDeviceControllerFactory knows about. - (void)shutDownCppController { + MTR_LOG("shutDownCppController MTRDeviceController: %p", self); assertChipStackLockedByCurrentThread(); // Shut down all our endpoints. @@ -605,13 +608,26 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams MTR_LOG("Loaded attribute values for %lu nodes from storage for controller uuid %@", static_cast(clusterDataByNode.count), self->_uniqueIdentifier); std::lock_guard lock(self->_deviceMapLock); + NSMutableArray * deviceList = [NSMutableArray array]; for (NSNumber * nodeID in clusterDataByNode) { NSDictionary * clusterData = clusterDataByNode[nodeID]; MTRDevice * device = [self _setupDeviceForNodeID:nodeID prefetchedClusterData:clusterData]; MTR_LOG("Loaded %lu cluster data from storage for %@", static_cast(clusterData.count), device); + + [deviceList addObject:device]; } + +#define kSecondsToWaitBeforeAPIClientRetainsMTRDevice 60 + // Keep the devices retained for a while, in case API client doesn't immediately retain them. + // + // Note that this is just an optimization to avoid throwing the information away and immediately + // re-reading it from storage. + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (kSecondsToWaitBeforeAPIClientRetainsMTRDevice * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + MTR_LOG("MTRDeviceController: un-retain devices loaded at startup %lu", static_cast(deviceList.count)); + }); }]; } + MTR_LOG("MTRDeviceController startup: %@", self); return YES; } @@ -1101,7 +1117,7 @@ - (NSData * _Nullable)attestationChallengeForDeviceID:(NSNumber *)deviceID chip::CommissioneeDeviceProxy * deviceProxy; auto errorCode = CHIP_NO_ERROR; - MATTER_LOG_METRIC_SCOPE(kMetricPASEVerifierForSetupCode, errorCode); + MATTER_LOG_METRIC_SCOPE(kMetricAttestationChallengeForDevice, errorCode); errorCode = self->_cppCommissioner->GetDeviceBeingCommissioned([deviceID unsignedLongLongValue], &deviceProxy); VerifyOrReturnValue(![MTRDeviceController checkForError:errorCode logMsg:kErrorGetCommissionee error:nil], nil); @@ -1247,7 +1263,7 @@ - (BOOL)checkIsRunning:(NSError * __autoreleasing *)error return YES; } - MTR_LOG_ERROR("Error: %s", [kErrorNotRunning UTF8String]); + MTR_LOG_ERROR("MTRDeviceController: %@ Error: %s", self, [kErrorNotRunning UTF8String]); if (error) { *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; } @@ -1257,15 +1273,12 @@ - (BOOL)checkIsRunning:(NSError * __autoreleasing *)error - (void)getSessionForNode:(chip::NodeId)nodeID completion:(MTRInternalDeviceConnectionCallback)completion { - // First check if MTRDevice exists from having loaded from storage, or created by a client. - // Do not use deviceForNodeID here, because we don't want to create the device if it does not already exist. - os_unfair_lock_lock(&_deviceMapLock); - MTRDevice * device = [_nodeIDToDeviceMap objectForKey:@(nodeID)]; - os_unfair_lock_unlock(&_deviceMapLock); + // Get the corresponding MTRDevice object to determine if the case/subscription pool is to be used + MTRDevice * device = [self deviceForNodeID:@(nodeID)]; // In the case that this device is known to use thread, queue this with subscription attempts as well, to // help with throttling Thread traffic. - if (device && [device deviceUsesThread]) { + if ([device deviceUsesThread]) { MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; [workItem setReadyHandler:^(id _Nonnull context, NSInteger retryCount, MTRAsyncWorkCompletionBlock _Nonnull workItemCompletion) { MTRInternalDeviceConnectionCallback completionWrapper = ^(chip::Messaging::ExchangeManager * _Nullable exchangeManager, @@ -1876,10 +1889,10 @@ - (BOOL)openPairingWindow:(uint64_t)deviceID duration:(NSUInteger)duration error return NO; } - __block CHIP_ERROR errorCode = CHIP_NO_ERROR; - MATTER_LOG_METRIC_SCOPE(kMetricOpenPairingWindow, errorCode); - auto block = ^BOOL { + CHIP_ERROR errorCode = CHIP_NO_ERROR; + MATTER_LOG_METRIC_SCOPE(kMetricOpenPairingWindow, errorCode); + errorCode = chip::Controller::AutoCommissioningWindowOpener::OpenBasicCommissioningWindow( self->_cppCommissioner, deviceID, chip::System::Clock::Seconds16(static_cast(duration))); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorOpenPairingWindow error:error]; diff --git a/src/darwin/Framework/CHIP/MTRError_Internal.h b/src/darwin/Framework/CHIP/MTRError_Internal.h index c79cc17d95f198..af19f4888ff050 100644 --- a/src/darwin/Framework/CHIP/MTRError_Internal.h +++ b/src/darwin/Framework/CHIP/MTRError_Internal.h @@ -26,6 +26,10 @@ NS_ASSUME_NONNULL_BEGIN +#ifndef YES_NO +#define YES_NO(x) ((x) ? @"YES" : @"NO") +#endif + MTR_DIRECT_MEMBERS @interface MTRError : NSObject + (NSError *)errorWithCode:(MTRErrorCode)code; diff --git a/src/darwin/Framework/CHIP/MTRMetricKeys.h b/src/darwin/Framework/CHIP/MTRMetricKeys.h index d20ec3395656a4..42064b7f049394 100644 --- a/src/darwin/Framework/CHIP/MTRMetricKeys.h +++ b/src/darwin/Framework/CHIP/MTRMetricKeys.h @@ -61,8 +61,11 @@ constexpr Tracing::MetricKey kMetricDeviceBeingCommissioned = "dwnfw_dev_being_c // Tracks the request to generate PASE verifier for a given setup code constexpr Tracing::MetricKey kMetricPASEVerifierForSetupCode = "dwnfw_pase_verifier_for_code"; +// Tracks the request to get attestation challenge for a device +constexpr Tracing::MetricKey kMetricAttestationChallengeForDevice = "dwnfw_attestation_challenge_for_device"; + // Marks the request to open pairing window -constexpr Tracing::MetricKey kMetricOpenPairingWindow = "dwnfw_pase_verifier_for_code"; +constexpr Tracing::MetricKey kMetricOpenPairingWindow = "dwnfw_open_pairing_window"; // Device Vendor ID constexpr Tracing::MetricKey kMetricDeviceVendorID = "dwnfw_device_vendor_id"; diff --git a/src/darwin/Framework/CHIP/templates/availability.yaml b/src/darwin/Framework/CHIP/templates/availability.yaml index 88241256e2eca2..5d8aef90a50d95 100644 --- a/src/darwin/Framework/CHIP/templates/availability.yaml +++ b/src/darwin/Framework/CHIP/templates/availability.yaml @@ -9689,10 +9689,12 @@ versions: "future" provisional: clusters: - # Targeting Fall 2024 + # Targeting 1.4 + - CommissionerControl - ServiceArea - ThreadBorderRouterManagement - ThreadNetworkDirectory + - WaterHeaterManagement - WiFiNetworkManagement attributes: OccupancySensing: @@ -9711,10 +9713,10 @@ - HoldTimeLimitsStruct bitmaps: OccupancySensing: - # Targeting Fall 1.4 + # Targeting 1.4 - Feature bitmap values: Switch: Feature: - # Targeting Fall 2024 + # Targeting 1.4 - ActionSwitch diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index 7785a04b904fa8..b735da19e2edf6 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -3053,6 +3053,51 @@ static BOOL AttributeIsSpecifiedInElectricalEnergyMeasurementCluster(AttributeId } } } +static BOOL AttributeIsSpecifiedInWaterHeaterManagementCluster(AttributeId aAttributeId) +{ + using namespace Clusters::WaterHeaterManagement; + switch (aAttributeId) { + case Attributes::HeaterTypes::Id: { + return YES; + } + case Attributes::HeatDemand::Id: { + return YES; + } + case Attributes::TankVolume::Id: { + return YES; + } + case Attributes::EstimatedHeatRequired::Id: { + return YES; + } + case Attributes::TankPercentage::Id: { + return YES; + } + case Attributes::BoostState::Id: { + return YES; + } + case Attributes::GeneratedCommandList::Id: { + return YES; + } + case Attributes::AcceptedCommandList::Id: { + return YES; + } + case Attributes::EventList::Id: { + return YES; + } + case Attributes::AttributeList::Id: { + return YES; + } + case Attributes::FeatureMap::Id: { + return YES; + } + case Attributes::ClusterRevision::Id: { + return YES; + } + default: { + return NO; + } + } +} static BOOL AttributeIsSpecifiedInDemandResponseLoadControlCluster(AttributeId aAttributeId) { using namespace Clusters::DemandResponseLoadControl; @@ -5951,6 +5996,36 @@ static BOOL AttributeIsSpecifiedInContentAppObserverCluster(AttributeId aAttribu } } } +static BOOL AttributeIsSpecifiedInCommissionerControlCluster(AttributeId aAttributeId) +{ + using namespace Clusters::CommissionerControl; + switch (aAttributeId) { + case Attributes::SupportedDeviceCategories::Id: { + return YES; + } + case Attributes::GeneratedCommandList::Id: { + return YES; + } + case Attributes::AcceptedCommandList::Id: { + return YES; + } + case Attributes::EventList::Id: { + return YES; + } + case Attributes::AttributeList::Id: { + return YES; + } + case Attributes::FeatureMap::Id: { + return YES; + } + case Attributes::ClusterRevision::Id: { + return YES; + } + default: { + return NO; + } + } +} static BOOL AttributeIsSpecifiedInElectricalMeasurementCluster(AttributeId aAttributeId) { using namespace Clusters::ElectricalMeasurement; @@ -6864,6 +6939,9 @@ BOOL MTRAttributeIsSpecified(ClusterId aClusterId, AttributeId aAttributeId) case Clusters::ElectricalEnergyMeasurement::Id: { return AttributeIsSpecifiedInElectricalEnergyMeasurementCluster(aAttributeId); } + case Clusters::WaterHeaterManagement::Id: { + return AttributeIsSpecifiedInWaterHeaterManagementCluster(aAttributeId); + } case Clusters::DemandResponseLoadControl::Id: { return AttributeIsSpecifiedInDemandResponseLoadControlCluster(aAttributeId); } @@ -7017,6 +7095,9 @@ BOOL MTRAttributeIsSpecified(ClusterId aClusterId, AttributeId aAttributeId) case Clusters::ContentAppObserver::Id: { return AttributeIsSpecifiedInContentAppObserverCluster(aAttributeId); } + case Clusters::CommissionerControl::Id: { + return AttributeIsSpecifiedInCommissionerControlCluster(aAttributeId); + } case Clusters::ElectricalMeasurement::Id: { return AttributeIsSpecifiedInElectricalMeasurementCluster(aAttributeId); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index d3780c91cf9eb4..d55efa91505867 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -8350,6 +8350,84 @@ static id _Nullable DecodeAttributeValueForElectricalEnergyMeasurementCluster(At *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; return nil; } +static id _Nullable DecodeAttributeValueForWaterHeaterManagementCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::WaterHeaterManagement; + switch (aAttributeId) { + case Attributes::HeaterTypes::Id: { + using TypeInfo = Attributes::HeaterTypes::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedChar:cppValue.Raw()]; + return value; + } + case Attributes::HeatDemand::Id: { + using TypeInfo = Attributes::HeatDemand::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedChar:cppValue.Raw()]; + return value; + } + case Attributes::TankVolume::Id: { + using TypeInfo = Attributes::TankVolume::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedShort:cppValue]; + return value; + } + case Attributes::EstimatedHeatRequired::Id: { + using TypeInfo = Attributes::EstimatedHeatRequired::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithLongLong:cppValue]; + return value; + } + case Attributes::TankPercentage::Id: { + using TypeInfo = Attributes::TankPercentage::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedChar:cppValue]; + return value; + } + case Attributes::BoostState::Id: { + using TypeInfo = Attributes::BoostState::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue)]; + return value; + } + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + return nil; +} static id _Nullable DecodeAttributeValueForDemandResponseLoadControlCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::DemandResponseLoadControl; @@ -16864,6 +16942,29 @@ static id _Nullable DecodeAttributeValueForContentAppObserverCluster(AttributeId *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; return nil; } +static id _Nullable DecodeAttributeValueForCommissionerControlCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::CommissionerControl; + switch (aAttributeId) { + case Attributes::SupportedDeviceCategories::Id: { + using TypeInfo = Attributes::SupportedDeviceCategories::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedInt:cppValue.Raw()]; + return value; + } + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + return nil; +} static id _Nullable DecodeAttributeValueForElectricalMeasurementCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::ElectricalMeasurement; @@ -19929,6 +20030,9 @@ id _Nullable MTRDecodeAttributeValue(const ConcreteAttributePath & aPath, TLV::T case Clusters::ElectricalEnergyMeasurement::Id: { return DecodeAttributeValueForElectricalEnergyMeasurementCluster(aPath.mAttributeId, aReader, aError); } + case Clusters::WaterHeaterManagement::Id: { + return DecodeAttributeValueForWaterHeaterManagementCluster(aPath.mAttributeId, aReader, aError); + } case Clusters::DemandResponseLoadControl::Id: { return DecodeAttributeValueForDemandResponseLoadControlCluster(aPath.mAttributeId, aReader, aError); } @@ -20082,6 +20186,9 @@ id _Nullable MTRDecodeAttributeValue(const ConcreteAttributePath & aPath, TLV::T case Clusters::ContentAppObserver::Id: { return DecodeAttributeValueForContentAppObserverCluster(aPath.mAttributeId, aReader, aError); } + case Clusters::CommissionerControl::Id: { + return DecodeAttributeValueForCommissionerControlCluster(aPath.mAttributeId, aReader, aError); + } case Clusters::ElectricalMeasurement::Id: { return DecodeAttributeValueForElectricalMeasurementCluster(aPath.mAttributeId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index fbf61defa7fe56..65a0a2bf3c2a3e 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -4936,8 +4936,8 @@ MTR_PROVISIONALLY_AVAILABLE /** * Cluster Laundry Dryer Controls * - * This cluster supports remotely monitoring and controling the different typs of - functionality available to a drying device, such as a laundry dryer. + * This cluster provides a way to access options associated with the operation of + a laundry dryer device type. */ MTR_PROVISIONALLY_AVAILABLE @interface MTRBaseClusterLaundryDryerControls : MTRGenericBaseCluster @@ -7502,6 +7502,118 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) @end +/** + * Cluster Water Heater Management + * + * This cluster is used to allow clients to control the operation of a hot water heating appliance so that it can be used with energy management. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRBaseClusterWaterHeaterManagement : MTRGenericBaseCluster + +/** + * Command Boost + * + * Allows a client to request that the water heater is put into a Boost state. + */ +- (void)boostWithParams:(MTRWaterHeaterManagementClusterBoostParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +/** + * Command CancelBoost + * + * Allows a client to cancel an ongoing Boost operation. + */ +- (void)cancelBoostWithParams:(MTRWaterHeaterManagementClusterCancelBoostParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)cancelBoostWithCompletion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeHeaterTypesWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeHeaterTypesWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeHeaterTypesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeHeatDemandWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeHeatDemandWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeHeatDemandWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeTankVolumeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeTankVolumeWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeTankVolumeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeEstimatedHeatRequiredWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeEstimatedHeatRequiredWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeEstimatedHeatRequiredWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeTankPercentageWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeTankPercentageWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeTankPercentageWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeBoostStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeBoostStateWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeBoostStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRBaseClusterWaterHeaterManagement (Availability) + +/** + * For all instance methods (reads, writes, commands) that take a completion, + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRBaseDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Demand Response Load Control * @@ -7917,13 +8029,13 @@ MTR_PROVISIONALLY_AVAILABLE /** * Command EnableCharging * - * Allows a client to enable the EVSE to charge an EV. + * This command allows a client to enable the EVSE to charge an EV, */ - (void)enableChargingWithParams:(MTREnergyEVSEClusterEnableChargingParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; /** * Command EnableDischarging * - * Allows a client to enable the EVSE to discharge an EV. + * Upon receipt, this SHALL allow a client to enable the discharge of an EV, */ - (void)enableDischargingWithParams:(MTREnergyEVSEClusterEnableDischargingParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; /** @@ -7943,7 +8055,7 @@ MTR_PROVISIONALLY_AVAILABLE /** * Command GetTargets * - * Allows a client to retrieve the user specified charging targets. + * Allows a client to retrieve the current set of charging targets. */ - (void)getTargetsWithParams:(MTREnergyEVSEClusterGetTargetsParams * _Nullable)params completion:(void (^)(MTREnergyEVSEClusterGetTargetsResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)getTargetsWithCompletion:(void (^)(MTREnergyEVSEClusterGetTargetsResponseParams * _Nullable data, NSError * _Nullable error))completion @@ -14867,6 +14979,86 @@ MTR_PROVISIONALLY_AVAILABLE @end +/** + * Cluster Commissioner Control + * + * Supports the ability for clients to request the commissioning of themselves or other nodes onto a fabric which the cluster server can commission onto. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRBaseClusterCommissionerControl : MTRGenericBaseCluster + +/** + * Command RequestCommissioningApproval + * + * This command is sent by a client to request approval for a future CommissionNode call. + */ +- (void)requestCommissioningApprovalWithParams:(MTRCommissionerControlClusterRequestCommissioningApprovalParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +/** + * Command CommissionNode + * + * This command is sent by a client to request that the server begins commissioning a previously approved request. + */ +- (void)commissionNodeWithParams:(MTRCommissionerControlClusterCommissionNodeParams *)params completion:(void (^)(MTRCommissionerControlClusterReverseOpenCommissioningWindowParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeSupportedDeviceCategoriesWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeSupportedDeviceCategoriesWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeSupportedDeviceCategoriesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRBaseClusterCommissionerControl (Availability) + +/** + * For all instance methods (reads, writes, commands) that take a completion, + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRBaseDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Electrical Measurement * @@ -18231,6 +18423,32 @@ typedef NS_OPTIONS(uint32_t, MTRElectricalEnergyMeasurementFeature) { MTRElectricalEnergyMeasurementFeaturePeriodicEnergy MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x8, } MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); +typedef NS_ENUM(uint8_t, MTRWaterHeaterManagementBoostState) { + MTRWaterHeaterManagementBoostStateInactive MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRWaterHeaterManagementBoostStateActive MTR_PROVISIONALLY_AVAILABLE = 0x01, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_OPTIONS(uint32_t, MTRWaterHeaterManagementFeature) { + MTRWaterHeaterManagementFeatureEnergyManagement MTR_PROVISIONALLY_AVAILABLE = 0x1, + MTRWaterHeaterManagementFeatureTankPercent MTR_PROVISIONALLY_AVAILABLE = 0x2, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_OPTIONS(uint8_t, MTRWaterHeaterManagementWaterHeaterDemandBitmap) { + MTRWaterHeaterManagementWaterHeaterDemandBitmapImmersionElement1 MTR_PROVISIONALLY_AVAILABLE = 0x1, + MTRWaterHeaterManagementWaterHeaterDemandBitmapImmersionElement2 MTR_PROVISIONALLY_AVAILABLE = 0x2, + MTRWaterHeaterManagementWaterHeaterDemandBitmapHeatPump MTR_PROVISIONALLY_AVAILABLE = 0x4, + MTRWaterHeaterManagementWaterHeaterDemandBitmapBoiler MTR_PROVISIONALLY_AVAILABLE = 0x8, + MTRWaterHeaterManagementWaterHeaterDemandBitmapOther MTR_PROVISIONALLY_AVAILABLE = 0x10, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_OPTIONS(uint8_t, MTRWaterHeaterManagementWaterHeaterTypeBitmap) { + MTRWaterHeaterManagementWaterHeaterTypeBitmapImmersionElement1 MTR_PROVISIONALLY_AVAILABLE = 0x1, + MTRWaterHeaterManagementWaterHeaterTypeBitmapImmersionElement2 MTR_PROVISIONALLY_AVAILABLE = 0x2, + MTRWaterHeaterManagementWaterHeaterTypeBitmapHeatPump MTR_PROVISIONALLY_AVAILABLE = 0x4, + MTRWaterHeaterManagementWaterHeaterTypeBitmapBoiler MTR_PROVISIONALLY_AVAILABLE = 0x8, + MTRWaterHeaterManagementWaterHeaterTypeBitmapOther MTR_PROVISIONALLY_AVAILABLE = 0x10, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_ENUM(uint8_t, MTRDemandResponseLoadControlCriticalityLevel) { MTRDemandResponseLoadControlCriticalityLevelUnknown MTR_PROVISIONALLY_AVAILABLE = 0x00, MTRDemandResponseLoadControlCriticalityLevelGreen MTR_PROVISIONALLY_AVAILABLE = 0x01, @@ -18461,6 +18679,7 @@ typedef NS_ENUM(uint8_t, MTREnergyEVSESupplyState) { MTREnergyEVSESupplyStateDischargingEnabled MTR_PROVISIONALLY_AVAILABLE = 0x02, MTREnergyEVSESupplyStateDisabledError MTR_PROVISIONALLY_AVAILABLE = 0x03, MTREnergyEVSESupplyStateDisabledDiagnostics MTR_PROVISIONALLY_AVAILABLE = 0x04, + MTREnergyEVSESupplyStateEnabled MTR_PROVISIONALLY_AVAILABLE = 0x05, } MTR_PROVISIONALLY_AVAILABLE; typedef NS_OPTIONS(uint32_t, MTREnergyEVSEFeature) { @@ -20581,6 +20800,10 @@ typedef NS_ENUM(uint8_t, MTRContentAppObserverStatus) { MTRContentAppObserverStatusUnexpectedData MTR_PROVISIONALLY_AVAILABLE = 0x01, } MTR_PROVISIONALLY_AVAILABLE; +typedef NS_OPTIONS(uint32_t, MTRCommissionerControlSupportedDeviceCategoryBitmap) { + MTRCommissionerControlSupportedDeviceCategoryBitmapFabricSynchronization MTR_PROVISIONALLY_AVAILABLE = 0x1, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_ENUM(uint8_t, MTRUnitTestingSimple) { MTRUnitTestingSimpleUnspecified MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00, MTRUnitTestingSimpleValueA MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x01, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index 87398bcf63b53e..fa9a4ef3fcf602 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -51085,6 +51085,495 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @end +@implementation MTRBaseClusterWaterHeaterManagement + +- (void)boostWithParams:(MTRWaterHeaterManagementClusterBoostParams *)params completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRWaterHeaterManagementClusterBoostParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WaterHeaterManagement::Commands::Boost::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} +- (void)cancelBoostWithCompletion:(MTRStatusCompletion)completion +{ + [self cancelBoostWithParams:nil completion:completion]; +} +- (void)cancelBoostWithParams:(MTRWaterHeaterManagementClusterCancelBoostParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRWaterHeaterManagementClusterCancelBoostParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WaterHeaterManagement::Commands::CancelBoost::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)readAttributeHeaterTypesWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::HeaterTypes::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeHeaterTypesWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterManagement::Attributes::HeaterTypes::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeHeaterTypesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::HeaterTypes::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeHeatDemandWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::HeatDemand::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeHeatDemandWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterManagement::Attributes::HeatDemand::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeHeatDemandWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::HeatDemand::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeTankVolumeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::TankVolume::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeTankVolumeWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterManagement::Attributes::TankVolume::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeTankVolumeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::TankVolume::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeEstimatedHeatRequiredWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::EstimatedHeatRequired::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeEstimatedHeatRequiredWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterManagement::Attributes::EstimatedHeatRequired::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeEstimatedHeatRequiredWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::EstimatedHeatRequired::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeTankPercentageWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::TankPercentage::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeTankPercentageWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterManagement::Attributes::TankPercentage::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeTankPercentageWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::TankPercentage::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeBoostStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::BoostState::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeBoostStateWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterManagement::Attributes::BoostState::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeBoostStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::BoostState::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::GeneratedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterManagement::Attributes::GeneratedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::GeneratedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::AcceptedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterManagement::Attributes::AcceptedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::AcceptedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::EventList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterManagement::Attributes::EventList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::EventList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::AttributeList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterManagement::Attributes::AttributeList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::AttributeList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::FeatureMap::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterManagement::Attributes::FeatureMap::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::FeatureMap::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::ClusterRevision::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterManagement::Attributes::ClusterRevision::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterManagement::Attributes::ClusterRevision::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +@end + @implementation MTRBaseClusterDemandResponseLoadControl - (void)registerLoadControlProgramRequestWithParams:(MTRDemandResponseLoadControlClusterRegisterLoadControlProgramRequestParams *)params completion:(MTRStatusCompletion)completion @@ -104178,6 +104667,311 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @end +@implementation MTRBaseClusterCommissionerControl + +- (void)requestCommissioningApprovalWithParams:(MTRCommissionerControlClusterRequestCommissioningApprovalParams *)params completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRCommissionerControlClusterRequestCommissioningApprovalParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = CommissionerControl::Commands::RequestCommissioningApproval::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} +- (void)commissionNodeWithParams:(MTRCommissionerControlClusterCommissionNodeParams *)params completion:(void (^)(MTRCommissionerControlClusterReverseOpenCommissioningWindowParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRCommissionerControlClusterCommissionNodeParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = CommissionerControl::Commands::CommissionNode::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRCommissionerControlClusterReverseOpenCommissioningWindowParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)readAttributeSupportedDeviceCategoriesWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::SupportedDeviceCategories::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeSupportedDeviceCategoriesWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = CommissionerControl::Attributes::SupportedDeviceCategories::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeSupportedDeviceCategoriesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::SupportedDeviceCategories::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::GeneratedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = CommissionerControl::Attributes::GeneratedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::GeneratedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::AcceptedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = CommissionerControl::Attributes::AcceptedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::AcceptedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::EventList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = CommissionerControl::Attributes::EventList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::EventList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::AttributeList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = CommissionerControl::Attributes::AttributeList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::AttributeList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::FeatureMap::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = CommissionerControl::Attributes::FeatureMap::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::FeatureMap::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::ClusterRevision::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = CommissionerControl::Attributes::ClusterRevision::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::ClusterRevision::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +@end + @implementation MTRBaseClusterElectricalMeasurement - (void)getProfileInfoCommandWithCompletion:(MTRStatusCompletion)completion diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 2b9d4fbba701d5..02230b74b6483f 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -151,6 +151,7 @@ typedef NS_ENUM(uint32_t, MTRClusterIDType) { MTRClusterIDTypeValveConfigurationAndControlID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x00000081, MTRClusterIDTypeElectricalPowerMeasurementID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x00000090, MTRClusterIDTypeElectricalEnergyMeasurementID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x00000091, + MTRClusterIDTypeWaterHeaterManagementID MTR_PROVISIONALLY_AVAILABLE = 0x00000094, MTRClusterIDTypeDemandResponseLoadControlID MTR_PROVISIONALLY_AVAILABLE = 0x00000096, MTRClusterIDTypeMessagesID MTR_PROVISIONALLY_AVAILABLE = 0x00000097, MTRClusterIDTypeDeviceEnergyManagementID MTR_PROVISIONALLY_AVAILABLE = 0x00000098, @@ -202,6 +203,7 @@ typedef NS_ENUM(uint32_t, MTRClusterIDType) { MTRClusterIDTypeAccountLoginID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000050E, MTRClusterIDTypeContentControlID MTR_PROVISIONALLY_AVAILABLE = 0x0000050F, MTRClusterIDTypeContentAppObserverID MTR_PROVISIONALLY_AVAILABLE = 0x00000510, + MTRClusterIDTypeCommissionerControlID MTR_PROVISIONALLY_AVAILABLE = 0x00000751, MTRClusterIDTypeElectricalMeasurementID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000B04, MTRClusterIDTypeUnitTestingID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0xFFF1FC05, MTRClusterIDTypeSampleMEIID MTR_PROVISIONALLY_AVAILABLE = 0xFFF1FC20, @@ -2624,6 +2626,20 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterElectricalEnergyMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterElectricalEnergyMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster WaterHeaterManagement attributes + MTRAttributeIDTypeClusterWaterHeaterManagementAttributeHeaterTypesID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRAttributeIDTypeClusterWaterHeaterManagementAttributeHeatDemandID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRAttributeIDTypeClusterWaterHeaterManagementAttributeTankVolumeID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRAttributeIDTypeClusterWaterHeaterManagementAttributeEstimatedHeatRequiredID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, + MTRAttributeIDTypeClusterWaterHeaterManagementAttributeTankPercentageID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, + MTRAttributeIDTypeClusterWaterHeaterManagementAttributeBoostStateID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, + MTRAttributeIDTypeClusterWaterHeaterManagementAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, + MTRAttributeIDTypeClusterWaterHeaterManagementAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, + MTRAttributeIDTypeClusterWaterHeaterManagementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, + MTRAttributeIDTypeClusterWaterHeaterManagementAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, + MTRAttributeIDTypeClusterWaterHeaterManagementAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, + MTRAttributeIDTypeClusterWaterHeaterManagementAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster DemandResponseLoadControl attributes MTRAttributeIDTypeClusterDemandResponseLoadControlAttributeLoadControlProgramsID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterDemandResponseLoadControlAttributeNumberOfLoadControlProgramsID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, @@ -4395,7 +4411,7 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeBorderAgentIDID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeThreadVersionID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeInterfaceEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, - MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeActiveDatasetTimestampID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, + MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeActiveDatasetTimestampID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, @@ -4859,6 +4875,15 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterContentAppObserverAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterContentAppObserverAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster CommissionerControl attributes + MTRAttributeIDTypeClusterCommissionerControlAttributeSupportedDeviceCategoriesID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRAttributeIDTypeClusterCommissionerControlAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, + MTRAttributeIDTypeClusterCommissionerControlAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, + MTRAttributeIDTypeClusterCommissionerControlAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, + MTRAttributeIDTypeClusterCommissionerControlAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, + MTRAttributeIDTypeClusterCommissionerControlAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, + MTRAttributeIDTypeClusterCommissionerControlAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster ElectricalMeasurement deprecated attribute names MTRClusterElectricalMeasurementAttributeMeasurementTypeID MTR_DEPRECATED("Please use MTRAttributeIDTypeClusterElectricalMeasurementAttributeMeasurementTypeID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) @@ -6326,6 +6351,10 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterValveConfigurationAndControlCommandOpenID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x00000000, MTRCommandIDTypeClusterValveConfigurationAndControlCommandCloseID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x00000001, + // Cluster WaterHeaterManagement commands + MTRCommandIDTypeClusterWaterHeaterManagementCommandBoostID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRCommandIDTypeClusterWaterHeaterManagementCommandCancelBoostID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + // Cluster DemandResponseLoadControl commands MTRCommandIDTypeClusterDemandResponseLoadControlCommandRegisterLoadControlProgramRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRCommandIDTypeClusterDemandResponseLoadControlCommandUnregisterLoadControlProgramRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, @@ -6641,9 +6670,9 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { // Cluster ThreadBorderRouterManagement commands MTRCommandIDTypeClusterThreadBorderRouterManagementCommandGetActiveDatasetRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRCommandIDTypeClusterThreadBorderRouterManagementCommandGetPendingDatasetRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, - MTRCommandIDTypeClusterThreadBorderRouterManagementCommandDatasetResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, - MTRCommandIDTypeClusterThreadBorderRouterManagementCommandSetActiveDatasetRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, - MTRCommandIDTypeClusterThreadBorderRouterManagementCommandSetPendingDatasetRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, + MTRCommandIDTypeClusterThreadBorderRouterManagementCommandDatasetResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRCommandIDTypeClusterThreadBorderRouterManagementCommandSetActiveDatasetRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, + MTRCommandIDTypeClusterThreadBorderRouterManagementCommandSetPendingDatasetRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, // Cluster ThreadNetworkDirectory commands MTRCommandIDTypeClusterThreadNetworkDirectoryCommandAddNetworkID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, @@ -6867,6 +6896,11 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterContentAppObserverCommandContentAppMessageID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRCommandIDTypeClusterContentAppObserverCommandContentAppMessageResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + // Cluster CommissionerControl commands + MTRCommandIDTypeClusterCommissionerControlCommandRequestCommissioningApprovalID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRCommandIDTypeClusterCommissionerControlCommandCommissionNodeID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRCommandIDTypeClusterCommissionerControlCommandReverseOpenCommissioningWindowID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + // Cluster ElectricalMeasurement deprecated command id names MTRClusterElectricalMeasurementCommandGetProfileInfoResponseCommandID MTR_DEPRECATED("Please use MTRCommandIDTypeClusterElectricalMeasurementCommandGetProfileInfoResponseCommandID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) @@ -7422,6 +7456,9 @@ typedef NS_ENUM(uint32_t, MTREventIDType) { // Cluster ContentControl events MTREventIDTypeClusterContentControlEventRemainingScreenTimeExpiredID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + // Cluster CommissionerControl events + MTREventIDTypeClusterCommissionerControlEventCommissioningRequestResultID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + // Cluster TestCluster deprecated event names MTRClusterTestClusterEventTestEventID MTR_DEPRECATED("Please use MTREventIDTypeClusterUnitTestingEventTestEventID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 48b47328a79ebb..4492c5895c3219 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -219,6 +219,9 @@ case MTRClusterIDTypeElectricalEnergyMeasurementID: result = @"ElectricalEnergyMeasurement"; break; + case MTRClusterIDTypeWaterHeaterManagementID: + result = @"WaterHeaterManagement"; + break; case MTRClusterIDTypeDemandResponseLoadControlID: result = @"DemandResponseLoadControl"; break; @@ -372,6 +375,9 @@ case MTRClusterIDTypeContentAppObserverID: result = @"ContentAppObserver"; break; + case MTRClusterIDTypeCommissionerControlID: + result = @"CommissionerControl"; + break; case MTRClusterIDTypeElectricalMeasurementID: result = @"ElectricalMeasurement"; break; @@ -4310,6 +4316,64 @@ break; } + case MTRClusterIDTypeWaterHeaterManagementID: + + switch (attributeID) { + + // Cluster WaterHeaterManagement attributes + case MTRAttributeIDTypeClusterWaterHeaterManagementAttributeHeaterTypesID: + result = @"HeaterTypes"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterManagementAttributeHeatDemandID: + result = @"HeatDemand"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterManagementAttributeTankVolumeID: + result = @"TankVolume"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterManagementAttributeEstimatedHeatRequiredID: + result = @"EstimatedHeatRequired"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterManagementAttributeTankPercentageID: + result = @"TankPercentage"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterManagementAttributeBoostStateID: + result = @"BoostState"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterManagementAttributeGeneratedCommandListID: + result = @"GeneratedCommandList"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterManagementAttributeAcceptedCommandListID: + result = @"AcceptedCommandList"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterManagementAttributeEventListID: + result = @"EventList"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterManagementAttributeAttributeListID: + result = @"AttributeList"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterManagementAttributeFeatureMapID: + result = @"FeatureMap"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterManagementAttributeClusterRevisionID: + result = @"ClusterRevision"; + break; + + default: + result = [NSString stringWithFormat:@"", attributeID]; + break; + } + case MTRClusterIDTypeDemandResponseLoadControlID: switch (attributeID) { @@ -8072,6 +8136,44 @@ break; } + case MTRClusterIDTypeCommissionerControlID: + + switch (attributeID) { + + // Cluster CommissionerControl attributes + case MTRAttributeIDTypeClusterCommissionerControlAttributeSupportedDeviceCategoriesID: + result = @"SupportedDeviceCategories"; + break; + + case MTRAttributeIDTypeClusterCommissionerControlAttributeGeneratedCommandListID: + result = @"GeneratedCommandList"; + break; + + case MTRAttributeIDTypeClusterCommissionerControlAttributeAcceptedCommandListID: + result = @"AcceptedCommandList"; + break; + + case MTRAttributeIDTypeClusterCommissionerControlAttributeEventListID: + result = @"EventList"; + break; + + case MTRAttributeIDTypeClusterCommissionerControlAttributeAttributeListID: + result = @"AttributeList"; + break; + + case MTRAttributeIDTypeClusterCommissionerControlAttributeFeatureMapID: + result = @"FeatureMap"; + break; + + case MTRAttributeIDTypeClusterCommissionerControlAttributeClusterRevisionID: + result = @"ClusterRevision"; + break; + + default: + result = [NSString stringWithFormat:@"", attributeID]; + break; + } + case MTRClusterIDTypeElectricalMeasurementID: switch (attributeID) { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 39024834ce0b37..1113a02929193b 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -2301,8 +2301,8 @@ MTR_PROVISIONALLY_AVAILABLE /** * Cluster Laundry Dryer Controls - * This cluster supports remotely monitoring and controling the different typs of - functionality available to a drying device, such as a laundry dryer. + * This cluster provides a way to access options associated with the operation of + a laundry dryer device type. */ MTR_PROVISIONALLY_AVAILABLE @interface MTRClusterLaundryDryerControls : MTRGenericCluster @@ -3550,6 +3550,59 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) @end +/** + * Cluster Water Heater Management + * This cluster is used to allow clients to control the operation of a hot water heating appliance so that it can be used with energy management. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRClusterWaterHeaterManagement : MTRGenericCluster + +- (void)boostWithParams:(MTRWaterHeaterManagementClusterBoostParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)cancelBoostWithParams:(MTRWaterHeaterManagementClusterCancelBoostParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)cancelBoostWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeHeaterTypesWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeHeatDemandWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeTankVolumeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeEstimatedHeatRequiredWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeTankPercentageWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeBoostStateWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRClusterWaterHeaterManagement (Availability) + +/** + * For all instance methods that take a completion (i.e. command invocations), + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Demand Response Load Control * This cluster provides an interface to the functionality of Smart Energy Demand Response and Load Control. @@ -6895,6 +6948,47 @@ MTR_PROVISIONALLY_AVAILABLE @end +/** + * Cluster Commissioner Control + * Supports the ability for clients to request the commissioning of themselves or other nodes onto a fabric which the cluster server can commission onto. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRClusterCommissionerControl : MTRGenericCluster + +- (void)requestCommissioningApprovalWithParams:(MTRCommissionerControlClusterRequestCommissioningApprovalParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)commissionNodeWithParams:(MTRCommissionerControlClusterCommissionNodeParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRCommissionerControlClusterReverseOpenCommissioningWindowParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeSupportedDeviceCategoriesWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRClusterCommissionerControl (Availability) + +/** + * For all instance methods that take a completion (i.e. command invocations), + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Electrical Measurement * Attributes related to the electrical properties of a device. This cluster is used by power outlets and other devices that need to provide instantaneous data as opposed to metrology data which should be retrieved from the metering cluster.. diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index 50a659cc520bb1..c9b3095c75b150 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -9285,6 +9285,128 @@ @implementation MTRClusterElectricalEnergyMeasurement @end +@implementation MTRClusterWaterHeaterManagement + +- (void)boostWithParams:(MTRWaterHeaterManagementClusterBoostParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRWaterHeaterManagementClusterBoostParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WaterHeaterManagement::Commands::Boost::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)cancelBoostWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self cancelBoostWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} +- (void)cancelBoostWithParams:(MTRWaterHeaterManagementClusterCancelBoostParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRWaterHeaterManagementClusterCancelBoostParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WaterHeaterManagement::Commands::CancelBoost::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} + +- (NSDictionary * _Nullable)readAttributeHeaterTypesWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterManagementID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterManagementAttributeHeaterTypesID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeHeatDemandWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterManagementID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterManagementAttributeHeatDemandID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeTankVolumeWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterManagementID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterManagementAttributeTankVolumeID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeEstimatedHeatRequiredWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterManagementID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterManagementAttributeEstimatedHeatRequiredID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeTankPercentageWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterManagementID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterManagementAttributeTankPercentageID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeBoostStateWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterManagementID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterManagementAttributeBoostStateID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterManagementID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterManagementAttributeGeneratedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterManagementID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterManagementAttributeAcceptedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterManagementID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterManagementAttributeEventListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterManagementID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterManagementAttributeAttributeListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterManagementID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterManagementAttributeFeatureMapID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterManagementID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterManagementAttributeClusterRevisionID) params:params]; +} + +@end + @implementation MTRClusterDemandResponseLoadControl - (void)registerLoadControlProgramRequestWithParams:(MTRDemandResponseLoadControlClusterRegisterLoadControlProgramRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion @@ -19784,6 +19906,99 @@ - (void)contentAppMessageWithParams:(MTRContentAppObserverClusterContentAppMessa @end +@implementation MTRClusterCommissionerControl + +- (void)requestCommissioningApprovalWithParams:(MTRCommissionerControlClusterRequestCommissioningApprovalParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRCommissionerControlClusterRequestCommissioningApprovalParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = CommissionerControl::Commands::RequestCommissioningApproval::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)commissionNodeWithParams:(MTRCommissionerControlClusterCommissionNodeParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRCommissionerControlClusterReverseOpenCommissioningWindowParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRCommissionerControlClusterCommissionNodeParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = CommissionerControl::Commands::CommissionNode::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRCommissionerControlClusterReverseOpenCommissioningWindowParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (NSDictionary * _Nullable)readAttributeSupportedDeviceCategoriesWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeSupportedDeviceCategoriesID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeGeneratedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeAcceptedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeEventListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeAttributeListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeFeatureMapID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeClusterRevisionID) params:params]; +} + +@end + @implementation MTRClusterElectricalMeasurement - (void)getProfileInfoCommandWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index 28051bd2275600..acb7982d9f9283 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -5362,6 +5362,74 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) @property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWaterHeaterManagementClusterBoostParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull duration MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nullable oneShot MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nullable emergencyBoost MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nullable temporarySetpoint MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nullable targetPercentage MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nullable targetReheat MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWaterHeaterManagementClusterCancelBoostParams : NSObject +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + MTR_PROVISIONALLY_AVAILABLE @interface MTRDemandResponseLoadControlClusterRegisterLoadControlProgramRequestParams : NSObject @@ -10737,6 +10805,105 @@ MTR_PROVISIONALLY_AVAILABLE error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRCommissionerControlClusterRequestCommissioningApprovalParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull requestId MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull vendorId MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull productId MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSString * _Nullable label MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRCommissionerControlClusterCommissionNodeParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull requestId MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull responseTimeoutSeconds MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSData * _Nullable ipAddress MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nullable port MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRCommissionerControlClusterReverseOpenCommissioningWindowParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull commissioningTimeout MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSData * _Nonnull pakePasscodeVerifier MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull discriminator MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull iterations MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSData * _Nonnull salt MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRCommissionerControlClusterReverseOpenCommissioningWindowParams with a response-value dictionary + * of the sort that MTRDeviceResponseHandler would receive. + * + * Will return nil and hand out an error if the response-value dictionary is not + * a command data response or is not the right command response. + * + * Will return nil and hand out an error if the data response does not match the known + * schema for this command. + */ +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRElectricalMeasurementClusterGetProfileInfoResponseCommandParams : NSObject diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index bacd761f42ffac..8ab9ac346812c5 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -15010,6 +15010,203 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end +@implementation MTRWaterHeaterManagementClusterBoostParams +- (instancetype)init +{ + if (self = [super init]) { + + _duration = @(0); + + _oneShot = nil; + + _emergencyBoost = nil; + + _temporarySetpoint = nil; + + _targetPercentage = nil; + + _targetReheat = nil; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRWaterHeaterManagementClusterBoostParams alloc] init]; + + other.duration = self.duration; + other.oneShot = self.oneShot; + other.emergencyBoost = self.emergencyBoost; + other.temporarySetpoint = self.temporarySetpoint; + other.targetPercentage = self.targetPercentage; + other.targetReheat = self.targetReheat; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: duration:%@; oneShot:%@; emergencyBoost:%@; temporarySetpoint:%@; targetPercentage:%@; targetReheat:%@; >", NSStringFromClass([self class]), _duration, _oneShot, _emergencyBoost, _temporarySetpoint, _targetPercentage, _targetReheat]; + return descriptionString; +} + +@end + +@implementation MTRWaterHeaterManagementClusterBoostParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::WaterHeaterManagement::Commands::Boost::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.duration = self.duration.unsignedIntValue; + } + { + if (self.oneShot != nil) { + auto & definedValue_0 = encodableStruct.oneShot.Emplace(); + definedValue_0 = self.oneShot.boolValue; + } + } + { + if (self.emergencyBoost != nil) { + auto & definedValue_0 = encodableStruct.emergencyBoost.Emplace(); + definedValue_0 = self.emergencyBoost.boolValue; + } + } + { + if (self.temporarySetpoint != nil) { + auto & definedValue_0 = encodableStruct.temporarySetpoint.Emplace(); + definedValue_0 = self.temporarySetpoint.shortValue; + } + } + { + if (self.targetPercentage != nil) { + auto & definedValue_0 = encodableStruct.targetPercentage.Emplace(); + definedValue_0 = self.targetPercentage.unsignedCharValue; + } + } + { + if (self.targetReheat != nil) { + auto & definedValue_0 = encodableStruct.targetReheat.Emplace(); + definedValue_0 = self.targetReheat.unsignedCharValue; + } + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRWaterHeaterManagementClusterCancelBoostParams +- (instancetype)init +{ + if (self = [super init]) { + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRWaterHeaterManagementClusterCancelBoostParams alloc] init]; + + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: >", NSStringFromClass([self class])]; + return descriptionString; +} + +@end + +@implementation MTRWaterHeaterManagementClusterCancelBoostParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::WaterHeaterManagement::Commands::CancelBoost::Type encodableStruct; + ListFreer listFreer; + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + @implementation MTRDemandResponseLoadControlClusterRegisterLoadControlProgramRequestParams - (instancetype)init { @@ -30836,6 +31033,312 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ContentA @end +@implementation MTRCommissionerControlClusterRequestCommissioningApprovalParams +- (instancetype)init +{ + if (self = [super init]) { + + _requestId = @(0); + + _vendorId = @(0); + + _productId = @(0); + + _label = nil; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRCommissionerControlClusterRequestCommissioningApprovalParams alloc] init]; + + other.requestId = self.requestId; + other.vendorId = self.vendorId; + other.productId = self.productId; + other.label = self.label; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: requestId:%@; vendorId:%@; productId:%@; label:%@; >", NSStringFromClass([self class]), _requestId, _vendorId, _productId, _label]; + return descriptionString; +} + +@end + +@implementation MTRCommissionerControlClusterRequestCommissioningApprovalParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.requestId = self.requestId.unsignedLongLongValue; + } + { + encodableStruct.vendorId = static_cast>(self.vendorId.unsignedShortValue); + } + { + encodableStruct.productId = self.productId.unsignedShortValue; + } + { + if (self.label != nil) { + auto & definedValue_0 = encodableStruct.label.Emplace(); + definedValue_0 = AsCharSpan(self.label); + } + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRCommissionerControlClusterCommissionNodeParams +- (instancetype)init +{ + if (self = [super init]) { + + _requestId = @(0); + + _responseTimeoutSeconds = @(0); + + _ipAddress = nil; + + _port = nil; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRCommissionerControlClusterCommissionNodeParams alloc] init]; + + other.requestId = self.requestId; + other.responseTimeoutSeconds = self.responseTimeoutSeconds; + other.ipAddress = self.ipAddress; + other.port = self.port; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: requestId:%@; responseTimeoutSeconds:%@; ipAddress:%@; port:%@; >", NSStringFromClass([self class]), _requestId, _responseTimeoutSeconds, [_ipAddress base64EncodedStringWithOptions:0], _port]; + return descriptionString; +} + +@end + +@implementation MTRCommissionerControlClusterCommissionNodeParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::CommissionerControl::Commands::CommissionNode::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.requestId = self.requestId.unsignedLongLongValue; + } + { + encodableStruct.responseTimeoutSeconds = self.responseTimeoutSeconds.unsignedShortValue; + } + { + if (self.ipAddress != nil) { + auto & definedValue_0 = encodableStruct.ipAddress.Emplace(); + definedValue_0 = AsByteSpan(self.ipAddress); + } + } + { + if (self.port != nil) { + auto & definedValue_0 = encodableStruct.port.Emplace(); + definedValue_0 = self.port.unsignedShortValue; + } + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRCommissionerControlClusterReverseOpenCommissioningWindowParams +- (instancetype)init +{ + if (self = [super init]) { + + _commissioningTimeout = @(0); + + _pakePasscodeVerifier = [NSData data]; + + _discriminator = @(0); + + _iterations = @(0); + + _salt = [NSData data]; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRCommissionerControlClusterReverseOpenCommissioningWindowParams alloc] init]; + + other.commissioningTimeout = self.commissioningTimeout; + other.pakePasscodeVerifier = self.pakePasscodeVerifier; + other.discriminator = self.discriminator; + other.iterations = self.iterations; + other.salt = self.salt; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: commissioningTimeout:%@; pakePasscodeVerifier:%@; discriminator:%@; iterations:%@; salt:%@; >", NSStringFromClass([self class]), _commissioningTimeout, [_pakePasscodeVerifier base64EncodedStringWithOptions:0], _discriminator, _iterations, [_salt base64EncodedStringWithOptions:0]]; + return descriptionString; +} + +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error +{ + if (!(self = [super init])) { + return nil; + } + + using DecodableType = chip::app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType; + chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue + clusterID:DecodableType::GetClusterId() + commandID:DecodableType::GetCommandId() + error:error]; + if (buffer.IsNull()) { + return nil; + } + + chip::TLV::TLVReader reader; + reader.Init(buffer->Start(), buffer->DataLength()); + + CHIP_ERROR err = reader.Next(chip::TLV::AnonymousTag()); + if (err == CHIP_NO_ERROR) { + DecodableType decodedStruct; + err = chip::app::DataModel::Decode(reader, decodedStruct); + if (err == CHIP_NO_ERROR) { + err = [self _setFieldsFromDecodableStruct:decodedStruct]; + if (err == CHIP_NO_ERROR) { + return self; + } + } + } + + NSString * errorStr = [NSString stringWithFormat:@"Command payload decoding failed: %s", err.AsString()]; + MTR_LOG_ERROR("%s", errorStr.UTF8String); + if (error != nil) { + NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : NSLocalizedString(errorStr, nil) }; + *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeSchemaMismatch userInfo:userInfo]; + } + return nil; +} + +@end + +@implementation MTRCommissionerControlClusterReverseOpenCommissioningWindowParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType &)decodableStruct +{ + { + self.commissioningTimeout = [NSNumber numberWithUnsignedShort:decodableStruct.commissioningTimeout]; + } + { + self.pakePasscodeVerifier = AsData(decodableStruct.PAKEPasscodeVerifier); + } + { + self.discriminator = [NSNumber numberWithUnsignedShort:decodableStruct.discriminator]; + } + { + self.iterations = [NSNumber numberWithUnsignedInt:decodableStruct.iterations]; + } + { + self.salt = AsData(decodableStruct.salt); + } + return CHIP_NO_ERROR; +} + +@end + @implementation MTRElectricalMeasurementClusterGetProfileInfoResponseCommandParams - (instancetype)init { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h index 963560ada35033..7072a0db6c26ef 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h @@ -1000,6 +1000,18 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRWaterHeaterManagementClusterBoostParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRWaterHeaterManagementClusterCancelBoostParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + @interface MTRDemandResponseLoadControlClusterRegisterLoadControlProgramRequestParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; @@ -2008,6 +2020,24 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRCommissionerControlClusterRequestCommissioningApprovalParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRCommissionerControlClusterCommissionNodeParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRCommissionerControlClusterReverseOpenCommissioningWindowParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType &)decodableStruct; + +@end + @interface MTRElectricalMeasurementClusterGetProfileInfoResponseCommandParams (InternalMethods) - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ElectricalMeasurement::Commands::GetProfileInfoResponseCommand::DecodableType &)decodableStruct; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm index 1b96c8c41201d5..5e09e32a955523 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm @@ -608,6 +608,15 @@ static BOOL CommandNeedsTimedInvokeInElectricalEnergyMeasurementCluster(Attribut } } } +static BOOL CommandNeedsTimedInvokeInWaterHeaterManagementCluster(AttributeId aAttributeId) +{ + using namespace Clusters::WaterHeaterManagement; + switch (aAttributeId) { + default: { + return NO; + } + } +} static BOOL CommandNeedsTimedInvokeInDemandResponseLoadControlCluster(AttributeId aAttributeId) { using namespace Clusters::DemandResponseLoadControl; @@ -1136,6 +1145,15 @@ static BOOL CommandNeedsTimedInvokeInContentAppObserverCluster(AttributeId aAttr } } } +static BOOL CommandNeedsTimedInvokeInCommissionerControlCluster(AttributeId aAttributeId) +{ + using namespace Clusters::CommissionerControl; + switch (aAttributeId) { + default: { + return NO; + } + } +} static BOOL CommandNeedsTimedInvokeInElectricalMeasurementCluster(AttributeId aAttributeId) { using namespace Clusters::ElectricalMeasurement; @@ -1365,6 +1383,9 @@ BOOL MTRCommandNeedsTimedInvoke(NSNumber * _Nonnull aClusterID, NSNumber * _Nonn case Clusters::ElectricalEnergyMeasurement::Id: { return CommandNeedsTimedInvokeInElectricalEnergyMeasurementCluster(commandID); } + case Clusters::WaterHeaterManagement::Id: { + return CommandNeedsTimedInvokeInWaterHeaterManagementCluster(commandID); + } case Clusters::DemandResponseLoadControl::Id: { return CommandNeedsTimedInvokeInDemandResponseLoadControlCluster(commandID); } @@ -1518,6 +1539,9 @@ BOOL MTRCommandNeedsTimedInvoke(NSNumber * _Nonnull aClusterID, NSNumber * _Nonn case Clusters::ContentAppObserver::Id: { return CommandNeedsTimedInvokeInContentAppObserverCluster(commandID); } + case Clusters::CommissionerControl::Id: { + return CommandNeedsTimedInvokeInCommissionerControlCluster(commandID); + } case Clusters::ElectricalMeasurement::Id: { return CommandNeedsTimedInvokeInElectricalMeasurementCluster(commandID); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm index 8de4f7c5966b50..049f67951b7408 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm @@ -2719,6 +2719,18 @@ static id _Nullable DecodeEventPayloadForElectricalEnergyMeasurementCluster(Even *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; return nil; } +static id _Nullable DecodeEventPayloadForWaterHeaterManagementCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::WaterHeaterManagement; + switch (aEventId) { + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + return nil; +} static id _Nullable DecodeEventPayloadForDemandResponseLoadControlCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::DemandResponseLoadControl; @@ -3144,6 +3156,15 @@ static id _Nullable DecodeEventPayloadForEnergyEVSECluster(EventId aEventId, TLV memberValue = [NSNumber numberWithLongLong:cppValue.maximumCurrent]; value.maximumCurrent = memberValue; } while (0); + do { + NSNumber * _Nullable memberValue; + if (cppValue.maximumDischargeCurrent.HasValue()) { + memberValue = [NSNumber numberWithLongLong:cppValue.maximumDischargeCurrent.Value()]; + } else { + memberValue = nil; + } + value.maximumDischargeCurrent = memberValue; + } while (0); return value; } @@ -3176,6 +3197,15 @@ static id _Nullable DecodeEventPayloadForEnergyEVSECluster(EventId aEventId, TLV memberValue = [NSNumber numberWithLongLong:cppValue.energyTransferred]; value.energyTransferred = memberValue; } while (0); + do { + NSNumber * _Nullable memberValue; + if (cppValue.energyDischarged.HasValue()) { + memberValue = [NSNumber numberWithLongLong:cppValue.energyDischarged.Value()]; + } else { + memberValue = nil; + } + value.energyDischarged = memberValue; + } while (0); return value; } @@ -4416,6 +4446,50 @@ static id _Nullable DecodeEventPayloadForContentAppObserverCluster(EventId aEven *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; return nil; } +static id _Nullable DecodeEventPayloadForCommissionerControlCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::CommissionerControl; + switch (aEventId) { + case Events::CommissioningRequestResult::Id: { + Events::CommissioningRequestResult::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + + __auto_type * value = [MTRCommissionerControlClusterCommissioningRequestResultEvent new]; + + do { + NSNumber * _Nonnull memberValue; + memberValue = [NSNumber numberWithUnsignedLongLong:cppValue.requestId]; + value.requestId = memberValue; + } while (0); + do { + NSNumber * _Nonnull memberValue; + memberValue = [NSNumber numberWithUnsignedLongLong:cppValue.clientNodeId]; + value.clientNodeId = memberValue; + } while (0); + do { + NSNumber * _Nonnull memberValue; + memberValue = [NSNumber numberWithUnsignedChar:cppValue.statusCode]; + value.statusCode = memberValue; + } while (0); + do { + NSNumber * _Nonnull memberValue; + memberValue = [NSNumber numberWithUnsignedChar:cppValue.fabricIndex]; + value.fabricIndex = memberValue; + } while (0); + + return value; + } + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + return nil; +} static id _Nullable DecodeEventPayloadForElectricalMeasurementCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::ElectricalMeasurement; @@ -4802,6 +4876,9 @@ id _Nullable MTRDecodeEventPayload(const ConcreteEventPath & aPath, TLV::TLVRead case Clusters::ElectricalEnergyMeasurement::Id: { return DecodeEventPayloadForElectricalEnergyMeasurementCluster(aPath.mEventId, aReader, aError); } + case Clusters::WaterHeaterManagement::Id: { + return DecodeEventPayloadForWaterHeaterManagementCluster(aPath.mEventId, aReader, aError); + } case Clusters::DemandResponseLoadControl::Id: { return DecodeEventPayloadForDemandResponseLoadControlCluster(aPath.mEventId, aReader, aError); } @@ -4955,6 +5032,9 @@ id _Nullable MTRDecodeEventPayload(const ConcreteEventPath & aPath, TLV::TLVRead case Clusters::ContentAppObserver::Id: { return DecodeEventPayloadForContentAppObserverCluster(aPath.mEventId, aReader, aError); } + case Clusters::CommissionerControl::Id: { + return DecodeEventPayloadForCommissionerControlCluster(aPath.mEventId, aReader, aError); + } case Clusters::ElectricalMeasurement::Id: { return DecodeEventPayloadForElectricalMeasurementCluster(aPath.mEventId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index 2301e63c1e5c38..e72e520b198f79 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -1410,6 +1410,7 @@ MTR_PROVISIONALLY_AVAILABLE @property (nonatomic, copy) NSNumber * _Nonnull sessionID MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nonnull state MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nonnull maximumCurrent MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable maximumDischargeCurrent MTR_PROVISIONALLY_AVAILABLE; @end MTR_PROVISIONALLY_AVAILABLE @@ -1418,6 +1419,7 @@ MTR_PROVISIONALLY_AVAILABLE @property (nonatomic, copy) NSNumber * _Nonnull state MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nonnull reason MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nonnull energyTransferred MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable energyDischarged MTR_PROVISIONALLY_AVAILABLE; @end MTR_PROVISIONALLY_AVAILABLE @@ -2037,6 +2039,14 @@ MTR_PROVISIONALLY_AVAILABLE @interface MTRContentControlClusterRemainingScreenTimeExpiredEvent : NSObject @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRCommissionerControlClusterCommissioningRequestResultEvent : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull requestId MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull clientNodeId MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull statusCode MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull fabricIndex MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) @interface MTRUnitTestingClusterSimpleStruct : NSObject @property (nonatomic, copy) NSNumber * _Nonnull a MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index 97031c54c37287..09314a688222f6 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -5787,6 +5787,8 @@ - (instancetype)init _state = @(0); _maximumCurrent = @(0); + + _maximumDischargeCurrent = nil; } return self; } @@ -5798,13 +5800,14 @@ - (id)copyWithZone:(NSZone * _Nullable)zone other.sessionID = self.sessionID; other.state = self.state; other.maximumCurrent = self.maximumCurrent; + other.maximumDischargeCurrent = self.maximumDischargeCurrent; return other; } - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: sessionID:%@; state:%@; maximumCurrent:%@; >", NSStringFromClass([self class]), _sessionID, _state, _maximumCurrent]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: sessionID:%@; state:%@; maximumCurrent:%@; maximumDischargeCurrent:%@; >", NSStringFromClass([self class]), _sessionID, _state, _maximumCurrent, _maximumDischargeCurrent]; return descriptionString; } @@ -5822,6 +5825,8 @@ - (instancetype)init _reason = @(0); _energyTransferred = @(0); + + _energyDischarged = nil; } return self; } @@ -5834,13 +5839,14 @@ - (id)copyWithZone:(NSZone * _Nullable)zone other.state = self.state; other.reason = self.reason; other.energyTransferred = self.energyTransferred; + other.energyDischarged = self.energyDischarged; return other; } - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: sessionID:%@; state:%@; reason:%@; energyTransferred:%@; >", NSStringFromClass([self class]), _sessionID, _state, _reason, _energyTransferred]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: sessionID:%@; state:%@; reason:%@; energyTransferred:%@; energyDischarged:%@; >", NSStringFromClass([self class]), _sessionID, _state, _reason, _energyTransferred, _energyDischarged]; return descriptionString; } @@ -8385,6 +8391,42 @@ - (NSString *)description @end +@implementation MTRCommissionerControlClusterCommissioningRequestResultEvent +- (instancetype)init +{ + if (self = [super init]) { + + _requestId = @(0); + + _clientNodeId = @(0); + + _statusCode = @(0); + + _fabricIndex = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRCommissionerControlClusterCommissioningRequestResultEvent alloc] init]; + + other.requestId = self.requestId; + other.clientNodeId = self.clientNodeId; + other.statusCode = self.statusCode; + other.fabricIndex = self.fabricIndex; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: requestId:%@; clientNodeId:%@; statusCode:%@; fabricIndex:%@; >", NSStringFromClass([self class]), _requestId, _clientNodeId, _statusCode, _fabricIndex]; + return descriptionString; +} + +@end + @implementation MTRUnitTestingClusterSimpleStruct - (instancetype)init { diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index 05037ef3e16822..df5949868d0012 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -2497,7 +2497,6 @@ "-Wl,-unexported_symbol,\"__Unwind_*\"", "-Wl,-unexported_symbol,\"_unw_*\"", "-Wl,-hidden-lCHIP", - "-Wl,-no_inits", ); "OTHER_LDFLAGS[sdk=macosx*]" = ( "-framework", @@ -2516,7 +2515,6 @@ "-Wl,-unexported_symbol,\"__Unwind_*\"", "-Wl,-unexported_symbol,\"_unw_*\"", "-Wl,-hidden-lCHIP", - "-Wl,-no_inits", ); PRODUCT_BUNDLE_IDENTIFIER = com.csa.matter; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; diff --git a/src/include/platform/internal/GenericConfigurationManagerImpl.ipp b/src/include/platform/internal/GenericConfigurationManagerImpl.ipp index bb9e56a8bb2a82..9b36f341042aa9 100644 --- a/src/include/platform/internal/GenericConfigurationManagerImpl.ipp +++ b/src/include/platform/internal/GenericConfigurationManagerImpl.ipp @@ -49,8 +49,6 @@ #include #endif -#include - // TODO : may be we can make it configurable #define BLE_ADVERTISEMENT_VERSION 0 @@ -58,9 +56,7 @@ namespace chip { namespace DeviceLayer { namespace Internal { -namespace { -std::optional gFirmwareBuildChipEpochTime; -} +static Optional sFirmwareBuildChipEpochTime; #if CHIP_USE_TRANSITIONAL_COMMISSIONABLE_DATA_PROVIDER @@ -292,9 +288,9 @@ template CHIP_ERROR GenericConfigurationManagerImpl::GetFirmwareBuildChipEpochTime(System::Clock::Seconds32 & chipEpochTime) { // If the setter was called and we have a value in memory, return this. - if (gFirmwareBuildChipEpochTime.has_value()) + if (sFirmwareBuildChipEpochTime.HasValue()) { - chipEpochTime = gFirmwareBuildChipEpochTime.value(); + chipEpochTime = sFirmwareBuildChipEpochTime.Value(); return CHIP_NO_ERROR; } #ifdef CHIP_DEVICE_CONFIG_FIRMWARE_BUILD_TIME_MATTER_EPOCH_S @@ -327,7 +323,7 @@ CHIP_ERROR GenericConfigurationManagerImpl::SetFirmwareBuildChipEpo // // Implementations that can't use the hard-coded time for whatever reason // should set this at each init. - gFirmwareBuildChipEpochTime = chipEpochTime; + sFirmwareBuildChipEpochTime.SetValue(chipEpochTime); return CHIP_NO_ERROR; } diff --git a/src/lib/address_resolve/AddressResolve.h b/src/lib/address_resolve/AddressResolve.h index 7dffeed01ed1d8..0d6f8ab719519d 100644 --- a/src/lib/address_resolve/AddressResolve.h +++ b/src/lib/address_resolve/AddressResolve.h @@ -33,7 +33,8 @@ struct ResolveResult { Transport::PeerAddress address; ReliableMessageProtocolConfig mrpRemoteConfig; - bool supportsTcp = false; + bool supportsTcpServer = false; + bool supportsTcpClient = false; bool isICDOperatingAsLIT = false; ResolveResult() : address(Transport::Type::kUdp), mrpRemoteConfig(GetDefaultMRPConfig()) {} diff --git a/src/lib/address_resolve/AddressResolve_DefaultImpl.cpp b/src/lib/address_resolve/AddressResolve_DefaultImpl.cpp index 5a9651ff76ba3d..e10146f4669793 100644 --- a/src/lib/address_resolve/AddressResolve_DefaultImpl.cpp +++ b/src/lib/address_resolve/AddressResolve_DefaultImpl.cpp @@ -287,8 +287,9 @@ void Resolver::OnOperationalNodeResolved(const Dnssd::ResolvedNodeData & nodeDat result.address.SetPort(nodeData.resolutionData.port); result.address.SetInterface(nodeData.resolutionData.interfaceId); - result.mrpRemoteConfig = nodeData.resolutionData.GetRemoteMRPConfig(); - result.supportsTcp = nodeData.resolutionData.supportsTcp; + result.mrpRemoteConfig = nodeData.resolutionData.GetRemoteMRPConfig(); + result.supportsTcpClient = nodeData.resolutionData.supportsTcpClient; + result.supportsTcpServer = nodeData.resolutionData.supportsTcpServer; if (nodeData.resolutionData.isICDOperatingAsLIT.has_value()) { diff --git a/src/lib/address_resolve/tool.cpp b/src/lib/address_resolve/tool.cpp index 8423649ca928a0..53d01b4011806f 100644 --- a/src/lib/address_resolve/tool.cpp +++ b/src/lib/address_resolve/tool.cpp @@ -56,7 +56,8 @@ class PrintOutNodeListener : public chip::AddressResolve::NodeListener result.address.ToString(addr_string); ChipLogProgress(Discovery, "Resolve completed: %s", addr_string); - ChipLogProgress(Discovery, " Supports TCP: %s", result.supportsTcp ? "YES" : "NO"); + ChipLogProgress(Discovery, " Supports TCP Client: %s", result.supportsTcpClient ? "YES" : "NO"); + ChipLogProgress(Discovery, " Supports TCP Server: %s", result.supportsTcpServer ? "YES" : "NO"); ChipLogProgress(Discovery, " MRP IDLE retransmit timeout: %u ms", result.mrpRemoteConfig.mIdleRetransTimeout.count()); ChipLogProgress(Discovery, " MRP ACTIVE retransmit timeout: %u ms", result.mrpRemoteConfig.mActiveRetransTimeout.count()); ChipLogProgress(Discovery, " MRP ACTIVE Threshold time: %u ms", result.mrpRemoteConfig.mActiveThresholdTime.count()); diff --git a/src/lib/dnssd/TxtFields.cpp b/src/lib/dnssd/TxtFields.cpp index 6ac2cfa19e8ece..20ca450b8734b5 100644 --- a/src/lib/dnssd/TxtFields.cpp +++ b/src/lib/dnssd/TxtFields.cpp @@ -38,6 +38,9 @@ namespace Dnssd { namespace Internal { +constexpr uint8_t kTCPClient = 1; +constexpr uint8_t kTCPServer = 2; + namespace { char SafeToLower(uint8_t ch) @@ -276,9 +279,13 @@ void FillNodeDataFromTxt(const ByteSpan & key, const ByteSpan & value, CommonRes case TxtFieldKey::kSessionActiveThreshold: nodeData.mrpRetryActiveThreshold = Internal::GetRetryActiveThreshold(value); break; - case TxtFieldKey::kTcpSupported: - nodeData.supportsTcp = Internal::MakeBoolFromAsciiDecimal(value); + case TxtFieldKey::kTcpSupported: { + // bit 0 is reserved and deprecated + uint8_t support = Internal::MakeU8FromAsciiDecimal(value); + nodeData.supportsTcpClient = (support & (1 << Internal::kTCPClient)) != 0; + nodeData.supportsTcpServer = (support & (1 << Internal::kTCPServer)) != 0; break; + } case TxtFieldKey::kLongIdleTimeICD: nodeData.isICDOperatingAsLIT = Internal::MakeOptionalBoolFromAsciiDecimal(value); break; diff --git a/src/lib/dnssd/Types.h b/src/lib/dnssd/Types.h index 1b9b19c0ad1bcc..60a265e46e425e 100644 --- a/src/lib/dnssd/Types.h +++ b/src/lib/dnssd/Types.h @@ -90,7 +90,8 @@ struct CommonResolutionData uint16_t port = 0; char hostName[kHostNameMaxLength + 1] = {}; - bool supportsTcp = false; + bool supportsTcpClient = false; + bool supportsTcpServer = false; std::optional isICDOperatingAsLIT; std::optional mrpRetryIntervalIdle; std::optional mrpRetryIntervalActive; @@ -131,7 +132,8 @@ struct CommonResolutionData isICDOperatingAsLIT = std::nullopt; numIPs = 0; port = 0; - supportsTcp = false; + supportsTcpClient = false; + supportsTcpServer = false; interfaceId = Inet::InterfaceId::Null(); for (auto & addr : ipAddress) { @@ -181,7 +183,8 @@ struct CommonResolutionData { ChipLogDetail(Discovery, "\tMrp Active Threshold: not present"); } - ChipLogDetail(Discovery, "\tTCP Supported: %d", supportsTcp); + ChipLogDetail(Discovery, "\tTCP Client Supported: %d", supportsTcpClient); + ChipLogDetail(Discovery, "\tTCP Server Supported: %d", supportsTcpServer); if (isICDOperatingAsLIT.has_value()) { ChipLogDetail(Discovery, "\tThe ICD operates in %s", *isICDOperatingAsLIT ? "LIT" : "SIT"); diff --git a/src/lib/dnssd/tests/TestIncrementalResolve.cpp b/src/lib/dnssd/tests/TestIncrementalResolve.cpp index 053d0dd96856ee..88e183b91ce2bb 100644 --- a/src/lib/dnssd/tests/TestIncrementalResolve.cpp +++ b/src/lib/dnssd/tests/TestIncrementalResolve.cpp @@ -308,7 +308,8 @@ TEST(TestIncrementalResolve, TestParseOperational) EXPECT_FALSE(nodeData.operationalData.hasZeroTTL); EXPECT_EQ(nodeData.resolutionData.numIPs, 1u); EXPECT_EQ(nodeData.resolutionData.port, 0x1234); - EXPECT_FALSE(nodeData.resolutionData.supportsTcp); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpServer); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpClient); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalActive().has_value()); EXPECT_EQ(nodeData.resolutionData.GetMrpRetryIntervalIdle(), std::make_optional(chip::System::Clock::Milliseconds32(23))); @@ -396,7 +397,8 @@ TEST(TestIncrementalResolve, TestParseCommissionable) // validate data as it was passed in EXPECT_EQ(nodeData.numIPs, 2u); EXPECT_EQ(nodeData.port, 0x1234); - EXPECT_FALSE(nodeData.supportsTcp); + EXPECT_FALSE(nodeData.supportsTcpClient); + EXPECT_FALSE(nodeData.supportsTcpServer); EXPECT_EQ(nodeData.GetMrpRetryIntervalActive(), std::make_optional(chip::System::Clock::Milliseconds32(321))); EXPECT_FALSE(nodeData.GetMrpRetryIntervalIdle().has_value()); diff --git a/src/lib/dnssd/tests/TestTxtFields.cpp b/src/lib/dnssd/tests/TestTxtFields.cpp index b80f1c0682ef32..873ce0bc4eb6f0 100644 --- a/src/lib/dnssd/tests/TestTxtFields.cpp +++ b/src/lib/dnssd/tests/TestTxtFields.cpp @@ -306,7 +306,8 @@ bool NodeDataIsEmpty(const CommissionNodeData & node) if (node.longDiscriminator != 0 || node.vendorId != 0 || node.productId != 0 || node.commissioningMode != 0 || node.deviceType != 0 || node.rotatingIdLen != 0 || node.pairingHint != 0 || node.mrpRetryIntervalIdle.has_value() || node.mrpRetryIntervalActive.has_value() || node.mrpRetryActiveThreshold.has_value() || - node.isICDOperatingAsLIT.has_value() || node.supportsTcp || node.supportsCommissionerGeneratedPasscode != 0) + node.isICDOperatingAsLIT.has_value() || node.supportsTcpServer || node.supportsTcpClient || + node.supportsCommissionerGeneratedPasscode != 0) { return false; } @@ -412,8 +413,8 @@ bool NodeDataIsEmpty(const ResolvedNodeData & nodeData) { return nodeData.operationalData.peerId == PeerId{} && nodeData.resolutionData.numIPs == 0 && nodeData.resolutionData.port == 0 && !nodeData.resolutionData.mrpRetryIntervalIdle.has_value() && - !nodeData.resolutionData.mrpRetryIntervalActive.has_value() && !nodeData.resolutionData.supportsTcp && - !nodeData.resolutionData.isICDOperatingAsLIT.has_value(); + !nodeData.resolutionData.mrpRetryIntervalActive.has_value() && !nodeData.resolutionData.supportsTcpClient && + !nodeData.resolutionData.supportsTcpServer && !nodeData.resolutionData.isICDOperatingAsLIT.has_value(); } void ResetRetryIntervalIdle(DiscoveredNodeData & nodeData) @@ -644,27 +645,80 @@ void DiscoveredTxtFieldTcpSupport() nodeData.Set(); CommonResolutionData & resolutionData = nodeData.Get(); - // True + // Neither TCP Client nor TCP Server are enabled + strcpy(key, "T"); + strcpy(val, "0"); + FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); + EXPECT_FALSE(nodeData.Get().supportsTcpServer); + EXPECT_FALSE(nodeData.Get().supportsTcpClient); + + // Neither TCP Client nor TCP Server are enabled - ignoring first bit strcpy(key, "T"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); - EXPECT_TRUE(nodeData.Get().supportsTcp); + EXPECT_FALSE(nodeData.Get().supportsTcpServer); + EXPECT_FALSE(nodeData.Get().supportsTcpClient); - // Test no other fields were populated - nodeData.Get().supportsTcp = false; - EXPECT_TRUE(NodeDataIsEmpty(nodeData.Get())); + // Supporting TCP Client only + strcpy(key, "T"); + strcpy(val, "2"); + FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); + EXPECT_TRUE(nodeData.Get().supportsTcpClient); + EXPECT_FALSE(nodeData.Get().supportsTcpServer); - // False + // Supporting TCP Client only - ignoring first bit strcpy(key, "T"); - strcpy(val, "0"); + strcpy(val, "3"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); - EXPECT_TRUE(nodeData.Get().supportsTcp == false); + EXPECT_TRUE(nodeData.Get().supportsTcpClient); + EXPECT_FALSE(nodeData.Get().supportsTcpServer); - // Invalid value, stil false + // Supporting TCP Server only + strcpy(key, "T"); + strcpy(val, "4"); + FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); + EXPECT_FALSE(nodeData.Get().supportsTcpClient); + EXPECT_TRUE(nodeData.Get().supportsTcpServer); + + // Supporting TCP Server only - ignoring first bit + strcpy(key, "T"); + strcpy(val, "5"); + FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); + EXPECT_FALSE(nodeData.Get().supportsTcpClient); + EXPECT_TRUE(nodeData.Get().supportsTcpServer); + + // Supporting TCP Server and Client + strcpy(key, "T"); + strcpy(val, "6"); + FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); + EXPECT_TRUE(nodeData.Get().supportsTcpClient); + EXPECT_TRUE(nodeData.Get().supportsTcpServer); + + // Supporting TCP Server and Client - ignoring first bit + strcpy(key, "T"); + strcpy(val, "7"); + FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); + EXPECT_TRUE(nodeData.Get().supportsTcpClient); + EXPECT_TRUE(nodeData.Get().supportsTcpServer); + + // Invalid value, means neither TCP Client or Server are enabled + strcpy(key, "T"); + strcpy(val, "8"); + FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); + EXPECT_FALSE(nodeData.Get().supportsTcpClient); + EXPECT_FALSE(nodeData.Get().supportsTcpServer); + + // Invalid value, means neither TCP Client or Server are enabled strcpy(key, "T"); strcpy(val, "asdf"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); - EXPECT_TRUE(nodeData.Get().supportsTcp == false); + EXPECT_FALSE(nodeData.Get().supportsTcpClient); + EXPECT_FALSE(nodeData.Get().supportsTcpServer); + + // Test no other fields were populated + nodeData.Get().supportsTcpClient = false; + nodeData.Get().supportsTcpServer = false; + EXPECT_TRUE(NodeDataIsEmpty(nodeData.Get())); } // Test ICD (ICD operation Mode) @@ -979,27 +1033,80 @@ void TxtFieldTcpSupport() char val[8]; NodeData nodeData; - // True + // Neither TCP Client nor TCP Server are enabled + strcpy(key, "T"); + strcpy(val, "0"); + FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpServer); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpClient); + + // Neither TCP Client nor TCP Server are enabled - ignoring first bit strcpy(key, "T"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - EXPECT_TRUE(nodeData.resolutionData.supportsTcp); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpServer); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpClient); - // Test no other fields were populated - nodeData.resolutionData.supportsTcp = false; - EXPECT_TRUE(NodeDataIsEmpty(nodeData)); + // Supporting TCP Client only + strcpy(key, "T"); + strcpy(val, "2"); + FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpServer); + EXPECT_TRUE(nodeData.resolutionData.supportsTcpClient); - // False + // Supporting TCP Client only - ignoring first bit strcpy(key, "T"); - strcpy(val, "0"); + strcpy(val, "3"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - EXPECT_EQ(nodeData.resolutionData.supportsTcp, false); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpServer); + EXPECT_TRUE(nodeData.resolutionData.supportsTcpClient); - // Invalid value, stil false + // Supporting TCP Server only + strcpy(key, "T"); + strcpy(val, "4"); + FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); + EXPECT_TRUE(nodeData.resolutionData.supportsTcpServer); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpClient); + + // Supporting TCP Server only - ignoring first bit + strcpy(key, "T"); + strcpy(val, "5"); + FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); + EXPECT_TRUE(nodeData.resolutionData.supportsTcpServer); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpClient); + + // Supporting TCP Server and Client + strcpy(key, "T"); + strcpy(val, "6"); + FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); + EXPECT_TRUE(nodeData.resolutionData.supportsTcpServer); + EXPECT_TRUE(nodeData.resolutionData.supportsTcpClient); + + // Supporting TCP Server and Client - ignoring first bit + strcpy(key, "T"); + strcpy(val, "7"); + FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); + EXPECT_TRUE(nodeData.resolutionData.supportsTcpServer); + EXPECT_TRUE(nodeData.resolutionData.supportsTcpClient); + + // Invalid value, means neither TCP Client or Server are enabled + strcpy(key, "T"); + strcpy(val, "8"); + FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpClient); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpServer); + + // Invalid value, means neither TCP Client or Server are enabled strcpy(key, "T"); strcpy(val, "asdf"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - EXPECT_EQ(nodeData.resolutionData.supportsTcp, false); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpClient); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpServer); + + // Test no other fields were populated + nodeData.resolutionData.supportsTcpServer = false; + nodeData.resolutionData.supportsTcpClient = false; + EXPECT_TRUE(NodeDataIsEmpty(nodeData)); } TEST(TestTxtFields, TxtDiscoveredFieldTcpSupport) diff --git a/src/lib/shell/commands/Config.cpp b/src/lib/shell/commands/Config.cpp index e1452f9b35ba67..cf5ac39e07983f 100644 --- a/src/lib/shell/commands/Config.cpp +++ b/src/lib/shell/commands/Config.cpp @@ -142,7 +142,7 @@ static CHIP_ERROR ConfigSetSetupDiscriminator(char * argv) } else { - streamer_printf(sout, "Setup discriminator setting failed with code: %d\r\n", error); + streamer_printf(sout, "Setup discriminator setting failed with code: %d\r\n", error.AsInteger()); } return error; diff --git a/src/lib/shell/commands/Dns.cpp b/src/lib/shell/commands/Dns.cpp index 50be591ddfeaee..18e0841dccce83 100644 --- a/src/lib/shell/commands/Dns.cpp +++ b/src/lib/shell/commands/Dns.cpp @@ -51,7 +51,8 @@ class DnsShellResolverDelegate : public Dnssd::DiscoverNodeDelegate, public Addr result.address.ToString(addr_string); streamer_printf(streamer_get(), "Resolve completed: %s\r\n", addr_string); - streamer_printf(streamer_get(), " Supports TCP: %s\r\n", result.supportsTcp ? "YES" : "NO"); + streamer_printf(streamer_get(), " Supports TCP Client: %s\r\n", result.supportsTcpClient ? "YES" : "NO"); + streamer_printf(streamer_get(), " Supports TCP Server: %s\r\n", result.supportsTcpServer ? "YES" : "NO"); streamer_printf(streamer_get(), " MRP IDLE retransmit timeout: %u ms\r\n", result.mrpRemoteConfig.mIdleRetransTimeout.count()); streamer_printf(streamer_get(), " MRP ACTIVE retransmit timeout: %u ms\r\n", @@ -121,20 +122,22 @@ class DnsShellResolverDelegate : public Dnssd::DiscoverNodeDelegate, public Addr auto retryInterval = nodeData.GetMrpRetryIntervalIdle(); if (retryInterval.has_value()) - streamer_printf(streamer_get(), " MRP retry interval (idle): %" PRIu32 "ms\r\n", *retryInterval); + streamer_printf(streamer_get(), " MRP retry interval (idle): %" PRIu32 "ms\r\n", retryInterval->count()); retryInterval = nodeData.GetMrpRetryIntervalActive(); if (retryInterval.has_value()) - streamer_printf(streamer_get(), " MRP retry interval (active): %" PRIu32 "ms\r\n", *retryInterval); + streamer_printf(streamer_get(), " MRP retry interval (active): %" PRIu32 "ms\r\n", retryInterval->count()); auto activeThreshold = nodeData.GetMrpRetryActiveThreshold(); if (activeThreshold.has_value()) { - streamer_printf(streamer_get(), " MRP retry active threshold time: %" PRIu32 "ms\r\n", *activeThreshold); + streamer_printf(streamer_get(), " MRP retry active threshold time: %" PRIu32 "ms\r\n", activeThreshold->count()); } - streamer_printf(streamer_get(), " Supports TCP: %s\r\n", nodeData.supportsTcp ? "yes" : "no"); + + streamer_printf(streamer_get(), " Supports TCP Client: %s\r\n", nodeData.supportsTcpClient ? "yes" : "no"); + streamer_printf(streamer_get(), " Supports TCP Server: %s\r\n", nodeData.supportsTcpServer ? "yes" : "no"); if (nodeData.isICDOperatingAsLIT.has_value()) { diff --git a/src/lib/support/IntrusiveList.h b/src/lib/support/IntrusiveList.h index be9c139babc3dc..961113e8d1ee6b 100644 --- a/src/lib/support/IntrusiveList.h +++ b/src/lib/support/IntrusiveList.h @@ -84,7 +84,7 @@ enum class IntrusiveMode class IntrusiveListNodePrivateBase { public: - constexpr IntrusiveListNodePrivateBase() : mPrev(nullptr), mNext(nullptr) {} + IntrusiveListNodePrivateBase() : mPrev(nullptr), mNext(nullptr) {} ~IntrusiveListNodePrivateBase() { VerifyOrDie(!IsInList()); } // Note: The copy construct/assignment is not provided because the list node state is not copyable. @@ -98,7 +98,7 @@ class IntrusiveListNodePrivateBase private: friend class IntrusiveListBase; - constexpr IntrusiveListNodePrivateBase(IntrusiveListNodePrivateBase * prev, IntrusiveListNodePrivateBase * next) : + IntrusiveListNodePrivateBase(IntrusiveListNodePrivateBase * prev, IntrusiveListNodePrivateBase * next) : mPrev(prev), mNext(next) {} @@ -284,7 +284,7 @@ class IntrusiveListBase // ^ | // \------------------------------------------/ // - constexpr IntrusiveListBase() : mNode(&mNode, &mNode) {} + IntrusiveListBase() : mNode(&mNode, &mNode) {} ~IntrusiveListBase() { VerifyOrDie(Empty()); @@ -399,7 +399,7 @@ template // nogncheck #endif -#include - namespace chip { using namespace System::Clock::Literals; #if CONFIG_BUILD_FOR_HOST_UNIT_TEST -namespace { -// Use std::optional for globals to avoid static initializers -std::optional gIdleRetransTimeoutOverride; -std::optional gActiveRetransTimeoutOverride; -std::optional gActiveThresholdTimeOverride; -} // namespace +static Optional idleRetransTimeoutOverride = NullOptional; +static Optional activeRetransTimeoutOverride = NullOptional; +static Optional activeThresholdTimeOverride = NullOptional; void OverrideLocalMRPConfig(System::Clock::Timeout idleRetransTimeout, System::Clock::Timeout activeRetransTimeout, System::Clock::Timeout activeThresholdTime) { - gIdleRetransTimeoutOverride = idleRetransTimeout; - gActiveRetransTimeoutOverride = activeRetransTimeout; - gActiveThresholdTimeOverride = activeThresholdTime; + idleRetransTimeoutOverride.SetValue(idleRetransTimeout); + activeRetransTimeoutOverride.SetValue(activeRetransTimeout); + activeThresholdTimeOverride.SetValue(activeThresholdTime); } void ClearLocalMRPConfigOverride() { - gActiveRetransTimeoutOverride = std::nullopt; - gIdleRetransTimeoutOverride = std::nullopt; - gActiveThresholdTimeOverride = std::nullopt; + activeRetransTimeoutOverride.ClearValue(); + idleRetransTimeoutOverride.ClearValue(); + activeThresholdTimeOverride.ClearValue(); } #endif @@ -67,15 +62,14 @@ namespace { // This is not a static member of ReliableMessageProtocolConfig because the free // function GetLocalMRPConfig() needs access to it. -// Use std::optional to avoid a static initializer -std::optional sDynamicLocalMPRConfig; +Optional sDynamicLocalMPRConfig; } // anonymous namespace bool ReliableMessageProtocolConfig::SetLocalMRPConfig(const Optional & localMRPConfig) { auto oldConfig = GetLocalMRPConfig(); - sDynamicLocalMPRConfig = localMRPConfig.std_optional(); + sDynamicLocalMPRConfig = localMRPConfig; return oldConfig != GetLocalMRPConfig(); } #endif // CHIP_DEVICE_CONFIG_ENABLE_DYNAMIC_MRP_CONFIG @@ -95,9 +89,9 @@ Optional GetLocalMRPConfig() ReliableMessageProtocolConfig config(CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL, CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL); #if CHIP_DEVICE_CONFIG_ENABLE_DYNAMIC_MRP_CONFIG - if (sDynamicLocalMPRConfig.has_value()) + if (sDynamicLocalMPRConfig.HasValue()) { - config = sDynamicLocalMPRConfig.value(); + config = sDynamicLocalMPRConfig.Value(); } #endif // CHIP_DEVICE_CONFIG_ENABLE_DYNAMIC_MRP_CONFIG @@ -111,19 +105,19 @@ Optional GetLocalMRPConfig() #endif #if CONFIG_BUILD_FOR_HOST_UNIT_TEST - if (gIdleRetransTimeoutOverride.has_value()) + if (idleRetransTimeoutOverride.HasValue()) { - config.mIdleRetransTimeout = gIdleRetransTimeoutOverride.value(); + config.mIdleRetransTimeout = idleRetransTimeoutOverride.Value(); } - if (gActiveRetransTimeoutOverride.has_value()) + if (activeRetransTimeoutOverride.HasValue()) { - config.mActiveRetransTimeout = gActiveRetransTimeoutOverride.value(); + config.mActiveRetransTimeout = activeRetransTimeoutOverride.Value(); } - if (gActiveThresholdTimeOverride.has_value()) + if (activeThresholdTimeOverride.HasValue()) { - config.mActiveThresholdTime = gActiveThresholdTimeOverride.value(); + config.mActiveThresholdTime = activeRetransTimeoutOverride.Value(); } #endif diff --git a/src/messaging/ReliableMessageProtocolConfig.h b/src/messaging/ReliableMessageProtocolConfig.h index f8d8cfa9bbf2fe..beceee6c52de46 100644 --- a/src/messaging/ReliableMessageProtocolConfig.h +++ b/src/messaging/ReliableMessageProtocolConfig.h @@ -191,9 +191,8 @@ inline constexpr System::Clock::Milliseconds32 kDefaultActiveTime = System::Cloc */ struct ReliableMessageProtocolConfig { - constexpr ReliableMessageProtocolConfig(System::Clock::Milliseconds32 idleInterval, - System::Clock::Milliseconds32 activeInterval, - System::Clock::Milliseconds16 activeThreshold = kDefaultActiveTime) : + ReliableMessageProtocolConfig(System::Clock::Milliseconds32 idleInterval, System::Clock::Milliseconds32 activeInterval, + System::Clock::Milliseconds16 activeThreshold = kDefaultActiveTime) : mIdleRetransTimeout(idleInterval), mActiveRetransTimeout(activeInterval), mActiveThresholdTime(activeThreshold) {} diff --git a/src/messaging/tests/BUILD.gn b/src/messaging/tests/BUILD.gn index 3232796aabe7e1..9cb017ea512c3a 100644 --- a/src/messaging/tests/BUILD.gn +++ b/src/messaging/tests/BUILD.gn @@ -32,6 +32,7 @@ static_library("helpers") { deps = [ "${chip_root}/src/credentials/tests:cert_test_vectors", "${chip_root}/src/lib/support:testing", + "${chip_root}/src/lib/support/tests:pw-test-macros", "${chip_root}/src/messaging", "${chip_root}/src/protocols", "${chip_root}/src/transport", diff --git a/src/messaging/tests/MessagingContext.cpp b/src/messaging/tests/MessagingContext.cpp index 909bc90f443575..c390f99096bb03 100644 --- a/src/messaging/tests/MessagingContext.cpp +++ b/src/messaging/tests/MessagingContext.cpp @@ -31,34 +31,34 @@ using namespace TestCerts; CHIP_ERROR MessagingContext::Init(TransportMgrBase * transport, IOContext * ioContext) { - VerifyOrReturnError(mInitialized == false, CHIP_ERROR_INTERNAL); - mInitialized = true; + VerifyOrReturnError(mpData->mInitialized == false, CHIP_ERROR_INTERNAL); + mpData->mInitialized = true; - mIOContext = ioContext; - mTransport = transport; + mpData->mIOContext = ioContext; + mpData->mTransport = transport; ReturnErrorOnFailure(PlatformMemoryUser::Init()); // Make sure the storage is clean, so we will not reuse any stale data. - mStorage.ClearStorage(); + mpData->mStorage.ClearStorage(); - ReturnErrorOnFailure(mOpKeyStore.Init(&mStorage)); - ReturnErrorOnFailure(mOpCertStore.Init(&mStorage)); + ReturnErrorOnFailure(mpData->mOpKeyStore.Init(&mpData->mStorage)); + ReturnErrorOnFailure(mpData->mOpCertStore.Init(&mpData->mStorage)); chip::FabricTable::InitParams initParams; - initParams.storage = &mStorage; - initParams.operationalKeystore = &mOpKeyStore; - initParams.opCertStore = &mOpCertStore; + initParams.storage = &mpData->mStorage; + initParams.operationalKeystore = &mpData->mOpKeyStore; + initParams.opCertStore = &mpData->mOpCertStore; - ReturnErrorOnFailure(mFabricTable.Init(initParams)); + ReturnErrorOnFailure(mpData->mFabricTable.Init(initParams)); - ReturnErrorOnFailure( - mSessionManager.Init(&GetSystemLayer(), transport, &mMessageCounterManager, &mStorage, &mFabricTable, mSessionKeystore)); + ReturnErrorOnFailure(mpData->mSessionManager.Init(&GetSystemLayer(), transport, &mpData->mMessageCounterManager, + &mpData->mStorage, &mpData->mFabricTable, mpData->mSessionKeystore)); - ReturnErrorOnFailure(mExchangeManager.Init(&mSessionManager)); - ReturnErrorOnFailure(mMessageCounterManager.Init(&mExchangeManager)); + ReturnErrorOnFailure(mpData->mExchangeManager.Init(&mpData->mSessionManager)); + ReturnErrorOnFailure(mpData->mMessageCounterManager.Init(&mpData->mExchangeManager)); - if (mInitializeNodes) + if (mpData->mInitializeNodes) { ReturnErrorOnFailure(CreateAliceFabric()); ReturnErrorOnFailure(CreateBobFabric()); @@ -80,15 +80,15 @@ CHIP_ERROR MessagingContext::Init(TransportMgrBase * transport, IOContext * ioCo // Shutdown all layers, finalize operations void MessagingContext::Shutdown() { - VerifyOrDie(mInitialized); - mInitialized = false; + VerifyOrDie(mpData->mInitialized); + mpData->mInitialized = false; - mMessageCounterManager.Shutdown(); - mExchangeManager.Shutdown(); - mSessionManager.Shutdown(); - mFabricTable.Shutdown(); - mOpCertStore.Finish(); - mOpKeyStore.Finish(); + mpData->mMessageCounterManager.Shutdown(); + mpData->mExchangeManager.Shutdown(); + mpData->mSessionManager.Shutdown(); + mpData->mFabricTable.Shutdown(); + mpData->mOpCertStore.Finish(); + mpData->mOpKeyStore.Finish(); // Reset the default additional MRP backoff. Messaging::ReliableMessageMgr::SetAdditionalMRPBackoffTime(NullOptional); @@ -96,7 +96,7 @@ void MessagingContext::Shutdown() CHIP_ERROR MessagingContext::InitFromExisting(const MessagingContext & existing) { - return Init(existing.mTransport, existing.mIOContext); + return Init(existing.mpData->mTransport, existing.mpData->mIOContext); } void MessagingContext::ShutdownAndRestoreExisting(MessagingContext & existing) @@ -104,7 +104,7 @@ void MessagingContext::ShutdownAndRestoreExisting(MessagingContext & existing) Shutdown(); // Point the transport back to the original session manager, since we had // pointed it to ours. - existing.mTransport->SetSessionManager(&existing.GetSecureSessionManager()); + existing.mpData->mTransport->SetSessionManager(&existing.GetSecureSessionManager()); } using namespace System::Clock::Literals; @@ -116,10 +116,10 @@ void MessagingContext::SetMRPMode(MRPMode mode) { if (mode == MRPMode::kDefault) { - mSessionBobToAlice->AsSecureSession()->SetRemoteSessionParameters(GetDefaultMRPConfig()); - mSessionAliceToBob->AsSecureSession()->SetRemoteSessionParameters(GetDefaultMRPConfig()); - mSessionCharlieToDavid->AsSecureSession()->SetRemoteSessionParameters(GetDefaultMRPConfig()); - mSessionDavidToCharlie->AsSecureSession()->SetRemoteSessionParameters(GetDefaultMRPConfig()); + mpData->mSessionBobToAlice->AsSecureSession()->SetRemoteSessionParameters(GetDefaultMRPConfig()); + mpData->mSessionAliceToBob->AsSecureSession()->SetRemoteSessionParameters(GetDefaultMRPConfig()); + mpData->mSessionCharlieToDavid->AsSecureSession()->SetRemoteSessionParameters(GetDefaultMRPConfig()); + mpData->mSessionDavidToCharlie->AsSecureSession()->SetRemoteSessionParameters(GetDefaultMRPConfig()); #if CONFIG_BUILD_FOR_HOST_UNIT_TEST ClearLocalMRPConfigOverride(); @@ -143,168 +143,174 @@ void MessagingContext::SetMRPMode(MRPMode mode) VerifyOrDie(false); #endif - mSessionBobToAlice->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig( + mpData->mSessionBobToAlice->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig( MessagingContext::kResponsiveIdleRetransTimeout, MessagingContext::kResponsiveActiveRetransTimeout)); - mSessionAliceToBob->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig( + mpData->mSessionAliceToBob->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig( MessagingContext::kResponsiveIdleRetransTimeout, MessagingContext::kResponsiveActiveRetransTimeout)); - mSessionCharlieToDavid->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig( + mpData->mSessionCharlieToDavid->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig( MessagingContext::kResponsiveIdleRetransTimeout, MessagingContext::kResponsiveActiveRetransTimeout)); - mSessionDavidToCharlie->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig( + mpData->mSessionDavidToCharlie->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig( MessagingContext::kResponsiveIdleRetransTimeout, MessagingContext::kResponsiveActiveRetransTimeout)); } } CHIP_ERROR MessagingContext::CreateAliceFabric() { - return mFabricTable.AddNewFabricForTestIgnoringCollisions(GetRootACertAsset().mCert, GetIAA1CertAsset().mCert, - GetNodeA1CertAsset().mCert, GetNodeA1CertAsset().mKey, - &mAliceFabricIndex); + return mpData->mFabricTable.AddNewFabricForTestIgnoringCollisions(GetRootACertAsset().mCert, GetIAA1CertAsset().mCert, + GetNodeA1CertAsset().mCert, GetNodeA1CertAsset().mKey, + &mpData->mAliceFabricIndex); } CHIP_ERROR MessagingContext::CreateBobFabric() { - return mFabricTable.AddNewFabricForTestIgnoringCollisions(GetRootACertAsset().mCert, GetIAA1CertAsset().mCert, - GetNodeA2CertAsset().mCert, GetNodeA2CertAsset().mKey, - &mBobFabricIndex); + return mpData->mFabricTable.AddNewFabricForTestIgnoringCollisions(GetRootACertAsset().mCert, GetIAA1CertAsset().mCert, + GetNodeA2CertAsset().mCert, GetNodeA2CertAsset().mKey, + &mpData->mBobFabricIndex); } CHIP_ERROR MessagingContext::CreateSessionBobToAlice() { - return mSessionManager.InjectPaseSessionWithTestKey(mSessionBobToAlice, kBobKeyId, GetAliceFabric()->GetNodeId(), kAliceKeyId, - mBobFabricIndex, mAliceAddress, CryptoContext::SessionRole::kInitiator); + return mpData->mSessionManager.InjectPaseSessionWithTestKey(mpData->mSessionBobToAlice, kBobKeyId, + GetAliceFabric()->GetNodeId(), kAliceKeyId, mpData->mBobFabricIndex, + mpData->mAliceAddress, CryptoContext::SessionRole::kInitiator); } CHIP_ERROR MessagingContext::CreateCASESessionBobToAlice() { - return mSessionManager.InjectCaseSessionWithTestKey(mSessionBobToAlice, kBobKeyId, kAliceKeyId, GetBobFabric()->GetNodeId(), - GetAliceFabric()->GetNodeId(), mBobFabricIndex, mAliceAddress, - CryptoContext::SessionRole::kInitiator); + return mpData->mSessionManager.InjectCaseSessionWithTestKey( + mpData->mSessionBobToAlice, kBobKeyId, kAliceKeyId, GetBobFabric()->GetNodeId(), GetAliceFabric()->GetNodeId(), + mpData->mBobFabricIndex, mpData->mAliceAddress, CryptoContext::SessionRole::kInitiator); } CHIP_ERROR MessagingContext::CreateCASESessionBobToAlice(const CATValues & cats) { - return mSessionManager.InjectCaseSessionWithTestKey(mSessionBobToAlice, kBobKeyId, kAliceKeyId, GetBobFabric()->GetNodeId(), - GetAliceFabric()->GetNodeId(), mBobFabricIndex, mAliceAddress, - CryptoContext::SessionRole::kInitiator, cats); + return mpData->mSessionManager.InjectCaseSessionWithTestKey( + mpData->mSessionBobToAlice, kBobKeyId, kAliceKeyId, GetBobFabric()->GetNodeId(), GetAliceFabric()->GetNodeId(), + mpData->mBobFabricIndex, mpData->mAliceAddress, CryptoContext::SessionRole::kInitiator, cats); } CHIP_ERROR MessagingContext::CreateSessionAliceToBob() { - return mSessionManager.InjectPaseSessionWithTestKey(mSessionAliceToBob, kAliceKeyId, GetBobFabric()->GetNodeId(), kBobKeyId, - mAliceFabricIndex, mBobAddress, CryptoContext::SessionRole::kResponder); + return mpData->mSessionManager.InjectPaseSessionWithTestKey(mpData->mSessionAliceToBob, kAliceKeyId, + GetBobFabric()->GetNodeId(), kBobKeyId, mpData->mAliceFabricIndex, + mpData->mBobAddress, CryptoContext::SessionRole::kResponder); } CHIP_ERROR MessagingContext::CreateCASESessionAliceToBob() { - return mSessionManager.InjectCaseSessionWithTestKey(mSessionAliceToBob, kAliceKeyId, kBobKeyId, GetAliceFabric()->GetNodeId(), - GetBobFabric()->GetNodeId(), mAliceFabricIndex, mBobAddress, - CryptoContext::SessionRole::kResponder); + return mpData->mSessionManager.InjectCaseSessionWithTestKey( + mpData->mSessionAliceToBob, kAliceKeyId, kBobKeyId, GetAliceFabric()->GetNodeId(), GetBobFabric()->GetNodeId(), + mpData->mAliceFabricIndex, mpData->mBobAddress, CryptoContext::SessionRole::kResponder); } CHIP_ERROR MessagingContext::CreateCASESessionAliceToBob(const CATValues & cats) { - return mSessionManager.InjectCaseSessionWithTestKey(mSessionAliceToBob, kAliceKeyId, kBobKeyId, GetAliceFabric()->GetNodeId(), - GetBobFabric()->GetNodeId(), mAliceFabricIndex, mBobAddress, - CryptoContext::SessionRole::kResponder, cats); + return mpData->mSessionManager.InjectCaseSessionWithTestKey( + mpData->mSessionAliceToBob, kAliceKeyId, kBobKeyId, GetAliceFabric()->GetNodeId(), GetBobFabric()->GetNodeId(), + mpData->mAliceFabricIndex, mpData->mBobAddress, CryptoContext::SessionRole::kResponder, cats); } CHIP_ERROR MessagingContext::CreatePASESessionCharlieToDavid() { - return mSessionManager.InjectPaseSessionWithTestKey(mSessionCharlieToDavid, kCharlieKeyId, 0xdeadbeef, kDavidKeyId, - kUndefinedFabricIndex, mDavidAddress, - CryptoContext::SessionRole::kInitiator); + return mpData->mSessionManager.InjectPaseSessionWithTestKey(mpData->mSessionCharlieToDavid, kCharlieKeyId, 0xdeadbeef, + kDavidKeyId, kUndefinedFabricIndex, mpData->mDavidAddress, + CryptoContext::SessionRole::kInitiator); } CHIP_ERROR MessagingContext::CreatePASESessionDavidToCharlie() { - return mSessionManager.InjectPaseSessionWithTestKey(mSessionDavidToCharlie, kDavidKeyId, 0xcafe, kCharlieKeyId, - kUndefinedFabricIndex, mCharlieAddress, - CryptoContext::SessionRole::kResponder); + return mpData->mSessionManager.InjectPaseSessionWithTestKey(mpData->mSessionDavidToCharlie, kDavidKeyId, 0xcafe, kCharlieKeyId, + kUndefinedFabricIndex, mpData->mCharlieAddress, + CryptoContext::SessionRole::kResponder); } CHIP_ERROR MessagingContext::CreateSessionBobToFriends() { - mSessionBobToFriends.Emplace(GetFriendsGroupId(), mBobFabricIndex); + mpData->mSessionBobToFriends.Emplace(GetFriendsGroupId(), mpData->mBobFabricIndex); return CHIP_NO_ERROR; } SessionHandle MessagingContext::GetSessionBobToAlice() { - auto sessionHandle = mSessionBobToAlice.Get(); + auto sessionHandle = mpData->mSessionBobToAlice.Get(); return std::move(sessionHandle.Value()); } SessionHandle MessagingContext::GetSessionAliceToBob() { - auto sessionHandle = mSessionAliceToBob.Get(); + auto sessionHandle = mpData->mSessionAliceToBob.Get(); return std::move(sessionHandle.Value()); } SessionHandle MessagingContext::GetSessionCharlieToDavid() { - auto sessionHandle = mSessionCharlieToDavid.Get(); + auto sessionHandle = mpData->mSessionCharlieToDavid.Get(); return std::move(sessionHandle.Value()); } SessionHandle MessagingContext::GetSessionDavidToCharlie() { - auto sessionHandle = mSessionDavidToCharlie.Get(); + auto sessionHandle = mpData->mSessionDavidToCharlie.Get(); return std::move(sessionHandle.Value()); } SessionHandle MessagingContext::GetSessionBobToFriends() { - return SessionHandle(mSessionBobToFriends.Value()); + return SessionHandle(mpData->mSessionBobToFriends.Value()); } void MessagingContext::ExpireSessionBobToAlice() { - if (mSessionBobToAlice) + if (mpData->mSessionBobToAlice) { - mSessionBobToAlice.Get().Value()->AsSecureSession()->MarkForEviction(); + mpData->mSessionBobToAlice.Get().Value()->AsSecureSession()->MarkForEviction(); } } void MessagingContext::ExpireSessionAliceToBob() { - if (mSessionAliceToBob) + if (mpData->mSessionAliceToBob) { - mSessionAliceToBob.Get().Value()->AsSecureSession()->MarkForEviction(); + mpData->mSessionAliceToBob.Get().Value()->AsSecureSession()->MarkForEviction(); } } void MessagingContext::ExpireSessionBobToFriends() { - mSessionBobToFriends.ClearValue(); + mpData->mSessionBobToFriends.ClearValue(); } Messaging::ExchangeContext * MessagingContext::NewUnauthenticatedExchangeToAlice(Messaging::ExchangeDelegate * delegate) { - return mExchangeManager.NewContext( - mSessionManager.CreateUnauthenticatedSession(mAliceAddress, GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig())).Value(), + return mpData->mExchangeManager.NewContext( + mpData->mSessionManager + .CreateUnauthenticatedSession(mpData->mAliceAddress, GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig())) + .Value(), delegate); } Messaging::ExchangeContext * MessagingContext::NewUnauthenticatedExchangeToBob(Messaging::ExchangeDelegate * delegate) { - return mExchangeManager.NewContext( - mSessionManager.CreateUnauthenticatedSession(mBobAddress, GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig())).Value(), + return mpData->mExchangeManager.NewContext( + mpData->mSessionManager + .CreateUnauthenticatedSession(mpData->mBobAddress, GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig())) + .Value(), delegate); } Messaging::ExchangeContext * MessagingContext::NewExchangeToAlice(Messaging::ExchangeDelegate * delegate, bool isInitiator) { - return mExchangeManager.NewContext(GetSessionBobToAlice(), delegate, isInitiator); + return mpData->mExchangeManager.NewContext(GetSessionBobToAlice(), delegate, isInitiator); } Messaging::ExchangeContext * MessagingContext::NewExchangeToBob(Messaging::ExchangeDelegate * delegate, bool isInitiator) { - return mExchangeManager.NewContext(GetSessionAliceToBob(), delegate, isInitiator); + return mpData->mExchangeManager.NewContext(GetSessionAliceToBob(), delegate, isInitiator); } -LoopbackTransportManager LoopbackMessagingContext::sLoopbackTransportManager; +LoopbackTransportManager * LoopbackMessagingContext::spLoopbackTransportManager = nullptr; -UDPTransportManager UDPMessagingContext::sUDPTransportManager; +UDPTransportManager * UDPMessagingContext::spUDPTransportManager = nullptr; void MessageCapturer::OnMessageReceived(const PacketHeader & packetHeader, const PayloadHeader & payloadHeader, const SessionHandle & session, DuplicateMessage isDuplicate, diff --git a/src/messaging/tests/MessagingContext.h b/src/messaging/tests/MessagingContext.h index f0e950a2cfc2a9..b5b16cbce73ab8 100644 --- a/src/messaging/tests/MessagingContext.h +++ b/src/messaging/tests/MessagingContext.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -92,16 +93,10 @@ class MessagingContext : public PlatformMemoryUser static constexpr System::Clock::Timeout kResponsiveIdleRetransTimeout = System::Clock::Milliseconds32(10); static constexpr System::Clock::Timeout kResponsiveActiveRetransTimeout = System::Clock::Milliseconds32(10); - MessagingContext() : - mInitialized(false), mAliceAddress(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT + 1)), - mBobAddress(LoopbackTransport::LoopbackPeer(mAliceAddress)) - {} - // TODO Replace VerifyOrDie with Pigweed assert after transition app/tests to Pigweed. - // TODO Currently src/app/icd/server/tests is using MessagingConetext as dependency. - ~MessagingContext() { VerifyOrDie(mInitialized == false); } + MessagingContext() : mpData(std::make_unique()) {} // Whether Alice and Bob are initialized, must be called before Init - void ConfigInitializeNodes(bool initializeNodes) { mInitializeNodes = initializeNodes; } + void ConfigInitializeNodes(bool initializeNodes) { mpData->mInitializeNodes = initializeNodes; } /// Initialize the underlying layers and test suite pointer CHIP_ERROR Init(TransportMgrBase * transport, IOContext * io); @@ -128,18 +123,18 @@ class MessagingContext : public PlatformMemoryUser static const uint16_t kAliceKeyId = 2; static const uint16_t kCharlieKeyId = 3; static const uint16_t kDavidKeyId = 4; - GroupId GetFriendsGroupId() const { return mFriendsGroupId; } + GroupId GetFriendsGroupId() const { return mpData->mFriendsGroupId; } - SessionManager & GetSecureSessionManager() { return mSessionManager; } - Messaging::ExchangeManager & GetExchangeManager() { return mExchangeManager; } - secure_channel::MessageCounterManager & GetMessageCounterManager() { return mMessageCounterManager; } - FabricTable & GetFabricTable() { return mFabricTable; } - Crypto::DefaultSessionKeystore & GetSessionKeystore() { return mSessionKeystore; } + SessionManager & GetSecureSessionManager() { return mpData->mSessionManager; } + Messaging::ExchangeManager & GetExchangeManager() { return mpData->mExchangeManager; } + secure_channel::MessageCounterManager & GetMessageCounterManager() { return mpData->mMessageCounterManager; } + FabricTable & GetFabricTable() { return mpData->mFabricTable; } + Crypto::DefaultSessionKeystore & GetSessionKeystore() { return mpData->mSessionKeystore; } - FabricIndex GetAliceFabricIndex() { return mAliceFabricIndex; } - FabricIndex GetBobFabricIndex() { return mBobFabricIndex; } - const FabricInfo * GetAliceFabric() { return mFabricTable.FindFabricWithIndex(mAliceFabricIndex); } - const FabricInfo * GetBobFabric() { return mFabricTable.FindFabricWithIndex(mBobFabricIndex); } + FabricIndex GetAliceFabricIndex() { return mpData->mAliceFabricIndex; } + FabricIndex GetBobFabricIndex() { return mpData->mBobFabricIndex; } + const FabricInfo * GetAliceFabric() { return mpData->mFabricTable.FindFabricWithIndex(mpData->mAliceFabricIndex); } + const FabricInfo * GetBobFabric() { return mpData->mFabricTable.FindFabricWithIndex(mpData->mBobFabricIndex); } CHIP_ERROR CreateSessionBobToAlice(); // Creates PASE session CHIP_ERROR CreateCASESessionBobToAlice(); @@ -166,8 +161,8 @@ class MessagingContext : public PlatformMemoryUser CHIP_ERROR CreateAliceFabric(); CHIP_ERROR CreateBobFabric(); - const Transport::PeerAddress & GetAliceAddress() { return mAliceAddress; } - const Transport::PeerAddress & GetBobAddress() { return mBobAddress; } + const Transport::PeerAddress & GetAliceAddress() { return mpData->mAliceAddress; } + const Transport::PeerAddress & GetBobAddress() { return mpData->mBobAddress; } Messaging::ExchangeContext * NewUnauthenticatedExchangeToAlice(Messaging::ExchangeDelegate * delegate); Messaging::ExchangeContext * NewUnauthenticatedExchangeToBob(Messaging::ExchangeDelegate * delegate); @@ -175,126 +170,149 @@ class MessagingContext : public PlatformMemoryUser Messaging::ExchangeContext * NewExchangeToAlice(Messaging::ExchangeDelegate * delegate, bool isInitiator = true); Messaging::ExchangeContext * NewExchangeToBob(Messaging::ExchangeDelegate * delegate, bool isInitiator = true); - System::Layer & GetSystemLayer() { return mIOContext->GetSystemLayer(); } + System::Layer & GetSystemLayer() { return mpData->mIOContext->GetSystemLayer(); } private: - bool mInitializeNodes = true; - bool mInitialized; - FabricTable mFabricTable; - - SessionManager mSessionManager; - Messaging::ExchangeManager mExchangeManager; - secure_channel::MessageCounterManager mMessageCounterManager; - IOContext * mIOContext; - TransportMgrBase * mTransport; // Only needed for InitFromExisting. - chip::TestPersistentStorageDelegate mStorage; // for SessionManagerInit - chip::PersistentStorageOperationalKeystore mOpKeyStore; - chip::Credentials::PersistentStorageOpCertStore mOpCertStore; - chip::Crypto::DefaultSessionKeystore mSessionKeystore; - - FabricIndex mAliceFabricIndex = kUndefinedFabricIndex; - FabricIndex mBobFabricIndex = kUndefinedFabricIndex; - GroupId mFriendsGroupId = 0x0101; - Transport::PeerAddress mAliceAddress; - Transport::PeerAddress mBobAddress; - Transport::PeerAddress mCharlieAddress; - Transport::PeerAddress mDavidAddress; - SessionHolder mSessionAliceToBob; - SessionHolder mSessionBobToAlice; - SessionHolder mSessionCharlieToDavid; - SessionHolder mSessionDavidToCharlie; - Optional mSessionBobToFriends; + // These members are encapsulated in a struct which is allocated upon construction of MessagingContext and freed upon + // destruction of MessagingContext. This is done to save stack space. + struct MessagingContextData + { + MessagingContextData() : + mAliceAddress(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT + 1)), + mBobAddress(LoopbackTransport::LoopbackPeer(mAliceAddress)) + {} + ~MessagingContextData() { EXPECT_FALSE(mInitialized); } + + bool mInitializeNodes = true; + bool mInitialized = false; + FabricTable mFabricTable; + + SessionManager mSessionManager; + Messaging::ExchangeManager mExchangeManager; + secure_channel::MessageCounterManager mMessageCounterManager; + IOContext * mIOContext = nullptr; + TransportMgrBase * mTransport = nullptr; // Only needed for InitFromExisting. + chip::TestPersistentStorageDelegate mStorage; // for SessionManagerInit + chip::PersistentStorageOperationalKeystore mOpKeyStore; + chip::Credentials::PersistentStorageOpCertStore mOpCertStore; + chip::Crypto::DefaultSessionKeystore mSessionKeystore; + + FabricIndex mAliceFabricIndex = kUndefinedFabricIndex; + FabricIndex mBobFabricIndex = kUndefinedFabricIndex; + GroupId mFriendsGroupId = 0x0101; + Transport::PeerAddress mAliceAddress; + Transport::PeerAddress mBobAddress; + Transport::PeerAddress mCharlieAddress; + Transport::PeerAddress mDavidAddress; + SessionHolder mSessionAliceToBob; + SessionHolder mSessionBobToAlice; + SessionHolder mSessionCharlieToDavid; + SessionHolder mSessionDavidToCharlie; + Optional mSessionBobToFriends; + }; + std::unique_ptr mpData; }; // LoopbackMessagingContext enriches MessagingContext with an async loopback transport -class LoopbackMessagingContext : public MessagingContext +class LoopbackMessagingContext : public ::testing::Test, public MessagingContext { public: virtual ~LoopbackMessagingContext() {} - // These functions wrap sLoopbackTransportManager methods - static auto & GetSystemLayer() { return sLoopbackTransportManager.GetSystemLayer(); } - static auto & GetLoopback() { return sLoopbackTransportManager.GetLoopback(); } - static auto & GetTransportMgr() { return sLoopbackTransportManager.GetTransportMgr(); } - static auto & GetIOContext() { return sLoopbackTransportManager.GetIOContext(); } + // These functions wrap spLoopbackTransportManager methods + static auto & GetSystemLayer() { return spLoopbackTransportManager->GetSystemLayer(); } + static auto & GetLoopback() { return spLoopbackTransportManager->GetLoopback(); } + static auto & GetTransportMgr() { return spLoopbackTransportManager->GetTransportMgr(); } + static auto & GetIOContext() { return spLoopbackTransportManager->GetIOContext(); } template static void DrainAndServiceIO(Ts... args) { - return sLoopbackTransportManager.DrainAndServiceIO(args...); + return spLoopbackTransportManager->DrainAndServiceIO(args...); } // Performs shared setup for all tests in the test suite static void SetUpTestSuite() { - CHIP_ERROR err = CHIP_NO_ERROR; - // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete - VerifyOrDieWithMsg((err = chip::Platform::MemoryInit()) == CHIP_NO_ERROR, AppServer, - "Init CHIP memory failed: %" CHIP_ERROR_FORMAT, err.Format()); - VerifyOrDieWithMsg((err = sLoopbackTransportManager.Init()) == CHIP_NO_ERROR, AppServer, - "Init LoopbackTransportManager failed: %" CHIP_ERROR_FORMAT, err.Format()); + // Initialize memory. + ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); + // Instantiate the LoopbackTransportManager. + ASSERT_EQ(spLoopbackTransportManager, nullptr); + spLoopbackTransportManager = new LoopbackTransportManager(); + ASSERT_NE(spLoopbackTransportManager, nullptr); + // Initialize the LoopbackTransportManager. + ASSERT_EQ(spLoopbackTransportManager->Init(), CHIP_NO_ERROR); } // Performs shared teardown for all tests in the test suite static void TearDownTestSuite() { - sLoopbackTransportManager.Shutdown(); + // Shutdown the LoopbackTransportManager. + spLoopbackTransportManager->Shutdown(); + // Destroy the LoopbackTransportManager. + if (spLoopbackTransportManager != nullptr) + { + delete spLoopbackTransportManager; + spLoopbackTransportManager = nullptr; + } + // Shutdown memory. chip::Platform::MemoryShutdown(); } // Performs setup for each individual test in the test suite - virtual void SetUp() - { - CHIP_ERROR err = CHIP_NO_ERROR; - VerifyOrDieWithMsg((err = MessagingContext::Init(&GetTransportMgr(), &GetIOContext())) == CHIP_NO_ERROR, AppServer, - "Init MessagingContext failed: %" CHIP_ERROR_FORMAT, err.Format()); - } + virtual void SetUp() { ASSERT_EQ(MessagingContext::Init(&GetTransportMgr(), &GetIOContext()), CHIP_NO_ERROR); } // Performs teardown for each individual test in the test suite virtual void TearDown() { MessagingContext::Shutdown(); } - static LoopbackTransportManager sLoopbackTransportManager; + static LoopbackTransportManager * spLoopbackTransportManager; }; // UDPMessagingContext enriches MessagingContext with an UDP transport -class UDPMessagingContext : public MessagingContext +class UDPMessagingContext : public ::testing::Test, public MessagingContext { public: virtual ~UDPMessagingContext() {} - static auto & GetSystemLayer() { return sUDPTransportManager.GetSystemLayer(); } - static auto & GetTransportMgr() { return sUDPTransportManager.GetTransportMgr(); } - static auto & GetIOContext() { return sUDPTransportManager.GetIOContext(); } + static auto & GetSystemLayer() { return spUDPTransportManager->GetSystemLayer(); } + static auto & GetTransportMgr() { return spUDPTransportManager->GetTransportMgr(); } + static auto & GetIOContext() { return spUDPTransportManager->GetIOContext(); } // Performs shared setup for all tests in the test suite static void SetUpTestSuite() { - CHIP_ERROR err = CHIP_NO_ERROR; - VerifyOrDieWithMsg((err = chip::Platform::MemoryInit()) == CHIP_NO_ERROR, AppServer, - "Init CHIP memory failed: %" CHIP_ERROR_FORMAT, err.Format()); - VerifyOrDieWithMsg((err = sUDPTransportManager.Init()) == CHIP_NO_ERROR, AppServer, - "Init UDPTransportManager failed: %" CHIP_ERROR_FORMAT, err.Format()); + // Initialize memory. + ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); + // Instantiate the UDPTransportManager. + ASSERT_EQ(spUDPTransportManager, nullptr); + spUDPTransportManager = new UDPTransportManager(); + ASSERT_NE(spUDPTransportManager, nullptr); + // Initialize the UDPTransportManager. + ASSERT_EQ(spUDPTransportManager->Init(), CHIP_NO_ERROR); } // Performs shared teardown for all tests in the test suite static void TearDownTestSuite() { - sUDPTransportManager.Shutdown(); + // Shutdown the UDPTransportManager. + spUDPTransportManager->Shutdown(); + // Destroy the UDPTransportManager. + if (spUDPTransportManager != nullptr) + { + delete spUDPTransportManager; + spUDPTransportManager = nullptr; + } + // Shutdown memory. chip::Platform::MemoryShutdown(); } // Performs setup for each individual test in the test suite - virtual void SetUp() - { - CHIP_ERROR err = CHIP_NO_ERROR; - VerifyOrDieWithMsg((err = MessagingContext::Init(&GetTransportMgr(), &GetIOContext())) == CHIP_NO_ERROR, AppServer, - "Init MessagingContext failed: %" CHIP_ERROR_FORMAT, err.Format()); - } + virtual void SetUp() { ASSERT_EQ(MessagingContext::Init(&GetTransportMgr(), &GetIOContext()), CHIP_NO_ERROR); } // Performs teardown for each individual test in the test suite virtual void TearDown() { MessagingContext::Shutdown(); } - static UDPTransportManager sUDPTransportManager; + static UDPTransportManager * spUDPTransportManager; }; // Class that can be used to capture decrypted message traffic in tests using diff --git a/src/messaging/tests/TestAbortExchangesForFabric.cpp b/src/messaging/tests/TestAbortExchangesForFabric.cpp index 8f8eb825553bf5..4d54a159bd27be 100644 --- a/src/messaging/tests/TestAbortExchangesForFabric.cpp +++ b/src/messaging/tests/TestAbortExchangesForFabric.cpp @@ -21,7 +21,7 @@ * one) for a fabric. */ -#include +#include #include #include @@ -48,12 +48,8 @@ using namespace chip::System; using namespace chip::System::Clock::Literals; using namespace chip::Protocols; -struct TestAbortExchangesForFabric : public chip::Test::LoopbackMessagingContext, public ::testing::Test +struct TestAbortExchangesForFabric : public chip::Test::LoopbackMessagingContext { - static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); } - - static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); } - void SetUp() override { #if CHIP_CRYPTO_PSA @@ -62,8 +58,6 @@ struct TestAbortExchangesForFabric : public chip::Test::LoopbackMessagingContext chip::Test::LoopbackMessagingContext::SetUp(); } - void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } - void CommonCheckAbortAllButOneExchange(bool dropResponseMessages); }; diff --git a/src/messaging/tests/TestExchange.cpp b/src/messaging/tests/TestExchange.cpp index 7c0257d3093d3f..ce8a89b3215aa7 100644 --- a/src/messaging/tests/TestExchange.cpp +++ b/src/messaging/tests/TestExchange.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include @@ -43,10 +43,8 @@ using namespace chip::Messaging; class MockExchangeDelegate; -struct TestExchange : public Test::LoopbackMessagingContext, public ::testing::Test +struct TestExchange : public Test::LoopbackMessagingContext { - // TODO Add TearDown function when changing test framework to Pigweed to make it more clear how it works. - // Currently, the TearDown function is from LoopbackMessagingContext void SetUp() override { #if CHIP_CRYPTO_PSA @@ -55,12 +53,6 @@ struct TestExchange : public Test::LoopbackMessagingContext, public ::testing::T chip::Test::LoopbackMessagingContext::SetUp(); } - void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } - - static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); } - - static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); } - template void DoRoundTripTest(MockExchangeDelegate & delegate1, MockExchangeDelegate & delegate2, uint8_t requestMessageType, uint8_t responseMessageType, AfterRequestChecker && afterRequestChecker, diff --git a/src/messaging/tests/TestExchangeHolder.cpp b/src/messaging/tests/TestExchangeHolder.cpp index 35f0856cfede24..44e28b48c2fae3 100644 --- a/src/messaging/tests/TestExchangeHolder.cpp +++ b/src/messaging/tests/TestExchangeHolder.cpp @@ -21,7 +21,7 @@ * one) for a fabric. */ -#include +#include #include "messaging/ExchangeDelegate.h" #include "system/SystemClock.h" @@ -68,16 +68,7 @@ using namespace chip::Messaging; using namespace chip::System; using namespace chip::Protocols; -struct TestExchangeHolder : public chip::Test::LoopbackMessagingContext, public ::testing::Test -{ - static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); } - - static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); } - - void SetUp() override { chip::Test::LoopbackMessagingContext::SetUp(); } - - void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } -}; +using TestExchangeHolder = chip::Test::LoopbackMessagingContext; class MockProtocolResponder : public ExchangeDelegate, public Messaging::UnsolicitedMessageHandler { diff --git a/src/messaging/tests/TestExchangeMgr.cpp b/src/messaging/tests/TestExchangeMgr.cpp index 975078ede9bd78..f944f7792d4b21 100644 --- a/src/messaging/tests/TestExchangeMgr.cpp +++ b/src/messaging/tests/TestExchangeMgr.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include @@ -47,12 +47,8 @@ using namespace chip::Inet; using namespace chip::Transport; using namespace chip::Messaging; -struct TestExchangeMgr : public chip::Test::LoopbackMessagingContext, public ::testing::Test +struct TestExchangeMgr : public chip::Test::LoopbackMessagingContext { - static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); } - - static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); } - void SetUp() override { #if CHIP_CRYPTO_PSA @@ -60,8 +56,6 @@ struct TestExchangeMgr : public chip::Test::LoopbackMessagingContext, public ::t #endif chip::Test::LoopbackMessagingContext::SetUp(); } - - void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } }; enum : uint8_t diff --git a/src/messaging/tests/TestMessagingLayer.cpp b/src/messaging/tests/TestMessagingLayer.cpp index 4e52cb96972ea6..eafffff1ce6753 100644 --- a/src/messaging/tests/TestMessagingLayer.cpp +++ b/src/messaging/tests/TestMessagingLayer.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include @@ -47,18 +47,7 @@ using namespace chip::Messaging; using namespace chip::Protocols; using namespace chip::System::Clock::Literals; -using TestContext = Test::UDPMessagingContext; - -struct TestMessagingLayer : public chip::Test::UDPMessagingContext, public ::testing::Test -{ - static void SetUpTestSuite() { chip::Test::UDPMessagingContext::SetUpTestSuite(); } - static void TearDownTestSuite() { chip::Test::UDPMessagingContext::TearDownTestSuite(); } - - // Performs setup for each individual test in the test suite - void SetUp() override { chip::Test::UDPMessagingContext::SetUp(); } - - void TearDown() override { chip::Test::UDPMessagingContext::TearDown(); } -}; +using TestMessagingLayer = chip::Test::UDPMessagingContext; // The message timeout value in milliseconds. constexpr System::Clock::Timeout kMessageTimeout = System::Clock::Milliseconds32(100); diff --git a/src/messaging/tests/TestReliableMessageProtocol.cpp b/src/messaging/tests/TestReliableMessageProtocol.cpp index d965c172a1c010..48e26b17b791dd 100644 --- a/src/messaging/tests/TestReliableMessageProtocol.cpp +++ b/src/messaging/tests/TestReliableMessageProtocol.cpp @@ -23,7 +23,7 @@ */ #include -#include +#include #include #include @@ -60,12 +60,9 @@ using namespace chip::System::Clock::Literals; const char PAYLOAD[] = "Hello!"; -class TestReliableMessageProtocol : public chip::Test::LoopbackMessagingContext, public ::testing::Test +class TestReliableMessageProtocol : public chip::Test::LoopbackMessagingContext { public: - static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); } - static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); } - // Performs setup for each individual test in the test suite void SetUp() override { @@ -76,8 +73,6 @@ class TestReliableMessageProtocol : public chip::Test::LoopbackMessagingContext, GetSessionAliceToBob()->AsSecureSession()->SetRemoteSessionParameters(GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig())); GetSessionBobToAlice()->AsSecureSession()->SetRemoteSessionParameters(GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig())); } - - void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } }; class MockAppDelegate : public UnsolicitedMessageHandler, public ExchangeDelegate @@ -502,7 +497,6 @@ TEST_F(TestReliableMessageProtocol, CheckResendApplicationMessage) TEST_F(TestReliableMessageProtocol, CheckCloseExchangeAndResendApplicationMessage) { - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); EXPECT_FALSE(buffer.IsNull()); @@ -561,7 +555,6 @@ TEST_F(TestReliableMessageProtocol, CheckCloseExchangeAndResendApplicationMessag TEST_F(TestReliableMessageProtocol, CheckFailedMessageRetainOnSend) { - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); EXPECT_FALSE(buffer.IsNull()); @@ -854,23 +847,18 @@ TEST_F(TestReliableMessageProtocol, CheckDuplicateOldMessageClosedExchange) TEST_F(TestReliableMessageProtocol, CheckResendSessionEstablishmentMessageWithPeerExchange) { - // Making this static to reduce stack usage, as some platforms have limits on stack size. - static chip::Test::MessagingContext ctx; - CHIP_ERROR err = ctx.InitFromExisting(*this); - EXPECT_EQ(err, CHIP_NO_ERROR); - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); ASSERT_FALSE(buffer.IsNull()); MockSessionEstablishmentDelegate mockReceiver; - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + CHIP_ERROR err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); EXPECT_EQ(err, CHIP_NO_ERROR); MockSessionEstablishmentDelegate mockSender; - ExchangeContext * exchange = ctx.NewUnauthenticatedExchangeToAlice(&mockSender); + ExchangeContext * exchange = NewUnauthenticatedExchangeToAlice(&mockSender); ASSERT_NE(exchange, nullptr); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); ASSERT_NE(rm, nullptr); exchange->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({ @@ -907,10 +895,8 @@ TEST_F(TestReliableMessageProtocol, CheckResendSessionEstablishmentMessageWithPe EXPECT_EQ(rm->TestGetCountRetransTable(), 0); EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); EXPECT_EQ(err, CHIP_NO_ERROR); - - ctx.ShutdownAndRestoreExisting(*this); } TEST_F(TestReliableMessageProtocol, CheckDuplicateMessage) diff --git a/src/platform/Darwin/ConfigurationManagerImpl.cpp b/src/platform/Darwin/ConfigurationManagerImpl.cpp index ae00faf58d81a1..10a2ad0a8eb600 100644 --- a/src/platform/Darwin/ConfigurationManagerImpl.cpp +++ b/src/platform/Darwin/ConfigurationManagerImpl.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -139,13 +138,10 @@ CHIP_ERROR GetMACAddressFromInterfaces(io_iterator_t primaryInterfaceIterator, u } #endif // TARGET_OS_OSX -namespace { -AtomicGlobal gInstance; -} - ConfigurationManagerImpl & ConfigurationManagerImpl::GetDefaultInstance() { - return gInstance.get(); + static ConfigurationManagerImpl sInstance; + return sInstance; } CHIP_ERROR ConfigurationManagerImpl::Init() diff --git a/src/platform/Darwin/ConfigurationManagerImpl.h b/src/platform/Darwin/ConfigurationManagerImpl.h index 5f99243b95adc4..74a13606be9c53 100644 --- a/src/platform/Darwin/ConfigurationManagerImpl.h +++ b/src/platform/Darwin/ConfigurationManagerImpl.h @@ -34,7 +34,7 @@ namespace chip { namespace DeviceLayer { -inline constexpr int kCountryCodeLength = 2; +static constexpr int kCountryCodeLength = 2; /** * Concrete implementation of the ConfigurationManager singleton object for the Darwin platform. diff --git a/src/platform/Darwin/DeviceInstanceInfoProviderImpl.cpp b/src/platform/Darwin/DeviceInstanceInfoProviderImpl.cpp index caf4e25191575e..6bb1d1bfd79c65 100644 --- a/src/platform/Darwin/DeviceInstanceInfoProviderImpl.cpp +++ b/src/platform/Darwin/DeviceInstanceInfoProviderImpl.cpp @@ -18,7 +18,6 @@ #include "DeviceInstanceInfoProviderImpl.h" -#include #include namespace chip { @@ -34,14 +33,5 @@ CHIP_ERROR DeviceInstanceInfoProviderImpl::GetProductId(uint16_t & productId) return Internal::PosixConfig::ReadConfigValue(Internal::PosixConfig::kConfigKey_ProductId, productId); } -namespace { -AtomicGlobal gInstance; -} // namespace - -DeviceInstanceInfoProviderImpl & DeviceInstanceInfoProviderMgrImpl() -{ - return gInstance.get(); -} - } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/Darwin/DeviceInstanceInfoProviderImpl.h b/src/platform/Darwin/DeviceInstanceInfoProviderImpl.h index 48603b583d9f86..630fdbe24c8a12 100644 --- a/src/platform/Darwin/DeviceInstanceInfoProviderImpl.h +++ b/src/platform/Darwin/DeviceInstanceInfoProviderImpl.h @@ -30,13 +30,15 @@ class DeviceInstanceInfoProviderImpl : public Internal::GenericDeviceInstanceInf CHIP_ERROR GetVendorId(uint16_t & vendorId) override; CHIP_ERROR GetProductId(uint16_t & productId) override; - DeviceInstanceInfoProviderImpl() : DeviceInstanceInfoProviderImpl(ConfigurationManagerImpl::GetDefaultInstance()) {} DeviceInstanceInfoProviderImpl(ConfigurationManagerImpl & configManager) : Internal::GenericDeviceInstanceInfoProvider(configManager) {} }; -DeviceInstanceInfoProviderImpl & DeviceInstanceInfoProviderMgrImpl(); - +inline DeviceInstanceInfoProviderImpl & DeviceInstanceInfoProviderMgrImpl() +{ + static DeviceInstanceInfoProviderImpl sInstance(ConfigurationManagerImpl::GetDefaultInstance()); + return sInstance; +} } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h b/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h index fba6a32fa26326..28e26038e6a3e2 100644 --- a/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h +++ b/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h @@ -106,3 +106,15 @@ #define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DISCOVERY 1 #define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 #endif + +#ifndef CHIP_DEVICE_CONFIG_USE_ZEPHYR_BLE +#define CHIP_DEVICE_CONFIG_USE_ZEPHYR_BLE 1 +#endif // CHIP_DEVICE_CONFIG_USE_ZEPHYR_BLE + +#ifndef CHIP_DEVICE_CONFIG_PROCESS_BLE_IN_THREAD +#define CHIP_DEVICE_CONFIG_PROCESS_BLE_IN_THREAD 0 +#endif // CHIP_DEVICE_CONFIG_PROCESS_BLE_IN_THREAD + +#ifndef CHIP_DEVICE_CONFIG_INIT_OT_PLAT_ALARM +#define CHIP_DEVICE_CONFIG_INIT_OT_PLAT_ALARM 1 +#endif // CHIP_DEVICE_CONFIG_INIT_OT_PLAT_ALARM diff --git a/src/platform/nxp/common/CHIPDevicePlatformEvent.h b/src/platform/nxp/common/CHIPDevicePlatformEvent.h index 4ea4ffcd304dbe..5c6a5c3c39ecf9 100644 --- a/src/platform/nxp/common/CHIPDevicePlatformEvent.h +++ b/src/platform/nxp/common/CHIPDevicePlatformEvent.h @@ -24,7 +24,7 @@ */ #pragma once -#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE && CHIP_DEVICE_CONFIG_USE_ZEPHYR_BLE #include #include #include @@ -74,7 +74,7 @@ enum InternalPlatformSpecificEventTypes } // namespace DeviceEventType -#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE && CHIP_DEVICE_CONFIG_USE_ZEPHYR_BLE struct BleConnEventType { bt_conn * BtConn; @@ -108,7 +108,7 @@ struct ChipDevicePlatformEvent final { union { -#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE && CHIP_DEVICE_CONFIG_USE_ZEPHYR_BLE BleConnEventType BleConnEvent; BleCCCWriteEventType BleCCCWriteEvent; BleC1WriteEventType BleC1WriteEvent; diff --git a/src/platform/nxp/common/CHIPNXPPlatformDefaultConfig.h b/src/platform/nxp/common/CHIPNXPPlatformDefaultConfig.h index 9282ffb5fe868e..0c263fc6ae3cfa 100644 --- a/src/platform/nxp/common/CHIPNXPPlatformDefaultConfig.h +++ b/src/platform/nxp/common/CHIPNXPPlatformDefaultConfig.h @@ -217,6 +217,34 @@ #define WDM_PUBLISHER_MAX_NOTIFIES_IN_FLIGHT 2 #endif // WDM_PUBLISHER_MAX_NOTIFIES_IN_FLIGHT +// ==================== ICD Configuration Overrides ==================== + +#ifndef NXP_ICD_ENABLED +#define NXP_ICD_ENABLED 0 +#endif // NXP_ICD_ENABLED + +#if NXP_ICD_ENABLED +#ifndef CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC +#define CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC NXP_IDLE_MODE_DURATION_SEC +#endif // CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC + +#ifndef CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS +#define CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS NXP_ACTIVE_MODE_DURATION_MS +#endif // CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS + +#ifndef CHIP_CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS +#define CHIP_CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS NXP_ACTIVE_MODE_THRESHOLD +#endif // CHIP_CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS + +#ifndef CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC +#define CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC NXP_ICD_SUPPORTED_CLIENTS_PER_FABRIC +#endif // CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC + +#ifndef CHIP_CONFIG_SYNCHRONOUS_REPORTS_ENABLED +#define CHIP_CONFIG_SYNCHRONOUS_REPORTS_ENABLED 1 +#endif +#endif // NXP_ICD_ENABLED + // ==================== Other Configuration Overrides ==================== #ifndef CHIP_CONFIG_RMP_DEFAULT_MAX_RETRANS diff --git a/src/platform/nxp/common/ConfigurationManagerImpl.cpp b/src/platform/nxp/common/ConfigurationManagerImpl.cpp index e99f913369eda8..ad8f00eaf3a4cb 100644 --- a/src/platform/nxp/common/ConfigurationManagerImpl.cpp +++ b/src/platform/nxp/common/ConfigurationManagerImpl.cpp @@ -33,6 +33,10 @@ #include "fsl_device_registers.h" +#if CONFIG_BOOT_REASON_SDK_SUPPORT +#include "fsl_power.h" +#endif + #if CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA #include "FactoryDataProvider.h" #endif @@ -54,12 +58,61 @@ ConfigurationManagerImpl & ConfigurationManagerImpl::GetDefaultInstance() return sInstance; } +#if CONFIG_BOOT_REASON_SDK_SUPPORT +CHIP_ERROR ConfigurationManagerImpl::DetermineBootReason(uint8_t rebootCause) +{ + /* + With current implementation kBrownOutReset couldn't be catched + */ + BootReasonType bootReason = BootReasonType::kUnspecified; + + if (rebootCause == 0) + { + bootReason = BootReasonType::kPowerOnReboot; + } + + else if (rebootCause == kPOWER_ResetCauseWdt) + { + /* Reboot can be due to hardware or software watchdog */ + bootReason = BootReasonType::kHardwareWatchdogReset; + } + else if (rebootCause == kPOWER_ResetCauseSysResetReq) + { + /* + kConfigKey_SoftwareUpdateCompleted not supported for now + if (NXPConfig::ConfigValueExists(NXPConfig::kConfigKey_SoftwareUpdateCompleted)) + { + bootReason = BootReasonType::kSoftwareUpdateCompleted; + } + else + { + bootReason = BootReasonType::kSoftwareReset; + } + */ + bootReason = BootReasonType::kSoftwareReset; + } + + return StoreBootReason(to_underlying(bootReason)); +} +#endif + +CHIP_ERROR ConfigurationManagerImpl::StoreSoftwareUpdateCompleted() +{ + /* Empty implementation*/ + return CHIP_NO_ERROR; +} + CHIP_ERROR ConfigurationManagerImpl::Init() { CHIP_ERROR err; uint32_t rebootCount = 0; bool failSafeArmed; +#if CONFIG_BOOT_REASON_SDK_SUPPORT + uint8_t rebootCause = POWER_GetResetCause(); + POWER_ClearResetCause(rebootCause); +#endif + // Initialize the generic implementation base class. err = Internal::GenericConfigurationManagerImpl::Init(); SuccessOrExit(err); @@ -84,12 +137,15 @@ CHIP_ERROR ConfigurationManagerImpl::Init() err = StoreTotalOperationalHours(0); SuccessOrExit(err); } - +#if CONFIG_BOOT_REASON_SDK_SUPPORT + SuccessOrExit(err = DetermineBootReason(rebootCause)); +#else if (!NXPConfig::ConfigValueExists(NXPConfig::kCounterKey_BootReason)) { err = StoreBootReason(to_underlying(BootReasonType::kUnspecified)); SuccessOrExit(err); } +#endif // TODO: Initialize the global GroupKeyStore object here diff --git a/src/platform/nxp/common/ConfigurationManagerImpl.h b/src/platform/nxp/common/ConfigurationManagerImpl.h index 062cc9dcac3901..e680942af6e6fe 100644 --- a/src/platform/nxp/common/ConfigurationManagerImpl.h +++ b/src/platform/nxp/common/ConfigurationManagerImpl.h @@ -39,6 +39,7 @@ class ConfigurationManagerImpl final : public Internal::GenericConfigurationMana public: // This returns an instance of this class. static ConfigurationManagerImpl & GetDefaultInstance(); + CHIP_ERROR StoreSoftwareUpdateCompleted(); private: // ===== Members that implement the ConfigurationManager public interface. @@ -78,6 +79,9 @@ class ConfigurationManagerImpl final : public Internal::GenericConfigurationMana // ===== Private members reserved for use by this class only. static void DoFactoryReset(intptr_t arg); +#if CONFIG_BOOT_REASON_SDK_SUPPORT + CHIP_ERROR DetermineBootReason(uint8_t rebootCause); +#endif }; /** diff --git a/src/platform/nxp/common/ConnectivityManagerImpl.cpp b/src/platform/nxp/common/ConnectivityManagerImpl.cpp index 0386de643455ef..cbdb866ae71973 100644 --- a/src/platform/nxp/common/ConnectivityManagerImpl.cpp +++ b/src/platform/nxp/common/ConnectivityManagerImpl.cpp @@ -32,10 +32,12 @@ #include #endif +#if CHIP_SYSTEM_CONFIG_USE_LWIP #include #include #include #include +#endif #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE #include diff --git a/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp b/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp index 0dd9b52f6a0aba..93a73d2767b8d3 100644 --- a/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp +++ b/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp @@ -29,7 +29,10 @@ #include #include + +#if CHIP_SYSTEM_CONFIG_USE_LWIP #include +#endif #if CHIP_DEVICE_CONFIG_ENABLE_WPA extern "C" { diff --git a/src/platform/nxp/common/ThreadStackManagerImpl.cpp b/src/platform/nxp/common/ThreadStackManagerImpl.cpp index b15ad60f0e9578..5667eefc7650ed 100644 --- a/src/platform/nxp/common/ThreadStackManagerImpl.cpp +++ b/src/platform/nxp/common/ThreadStackManagerImpl.cpp @@ -20,8 +20,7 @@ /** * @file * Provides an implementation of the ThreadStackManager object for - * NXP platforms using the NXP SDK and the OpenThread - * stack. + * NXP platforms using the NXP SDK and the OpenThread stack. * */ @@ -32,7 +31,11 @@ #include #include +#if CHIP_SYSTEM_CONFIG_USE_LWIP #include +#else +#include +#endif #include @@ -59,21 +62,44 @@ CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack(void) { CHIP_ERROR err = CHIP_NO_ERROR; +#if CHIP_DEVICE_CONFIG_INIT_OT_PLAT_ALARM /* Initialize the OpenThread Alarm module to make sure that if calling otInstance, * it can schedule events */ otPlatAlarmInit(); +#endif // Initialize the generic implementation base classes. err = GenericThreadStackManagerImpl_FreeRTOS::DoInit(); SuccessOrExit(err); +#if CHIP_SYSTEM_CONFIG_USE_LWIP err = GenericThreadStackManagerImpl_OpenThread_LwIP::DoInit(NULL); +#else + err = GenericThreadStackManagerImpl_OpenThread::DoInit(NULL); +#endif SuccessOrExit(err); exit: return err; } +#if CHIP_DEVICE_CONFIG_PROCESS_BLE_IN_THREAD +void ThreadStackManagerImpl::ProcessThreadActivity() +{ + /* reuse thread task for ble processing. + * by doing this, we avoid allocating a new stack for short-lived + * BLE processing (e.g.: only during Matter commissioning) + */ +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + auto * bleManager = &chip::DeviceLayer::Internal::BLEMgrImpl(); + bleManager->DoBleProcessing(); +#endif + + otTaskletsProcess(OTInstance()); + otSysProcessDrivers(OTInstance()); +} +#endif + bool ThreadStackManagerImpl::IsInitialized() { return sInstance.mThreadStackLock != NULL; @@ -112,3 +138,8 @@ extern "C" void otPlatFree(void * aPtr) { return CHIPPlatformMemoryFree(aPtr); } + +extern "C" void * otPlatRealloc(void * p, size_t aSize) +{ + return CHIPPlatformMemoryRealloc(p, aSize); +} diff --git a/src/platform/nxp/common/ThreadStackManagerImpl.h b/src/platform/nxp/common/ThreadStackManagerImpl.h index 6f9fae80950670..83990db21569dc 100644 --- a/src/platform/nxp/common/ThreadStackManagerImpl.h +++ b/src/platform/nxp/common/ThreadStackManagerImpl.h @@ -28,7 +28,11 @@ #include #include #include +#if CHIP_SYSTEM_CONFIG_USE_LWIP #include +#else +#include +#endif extern "C" void otSysEventSignalPending(void); @@ -43,7 +47,11 @@ class ThreadStackManagerImpl; * using the NXP SDK and the OpenThread stack. */ class ThreadStackManagerImpl final : public ThreadStackManager, +#if CHIP_SYSTEM_CONFIG_USE_LWIP public Internal::GenericThreadStackManagerImpl_OpenThread_LwIP, +#else + public Internal::GenericThreadStackManagerImpl_OpenThread, +#endif public Internal::GenericThreadStackManagerImpl_FreeRTOS { // Allow the ThreadStackManager interface class to delegate method calls to @@ -53,8 +61,11 @@ class ThreadStackManagerImpl final : public ThreadStackManager, // Allow the generic implementation base classes to call helper methods on // this class. #ifndef DOXYGEN_SHOULD_SKIP_THIS - friend Internal::GenericThreadStackManagerImpl_OpenThread; +#if CHIP_SYSTEM_CONFIG_USE_LWIP friend Internal::GenericThreadStackManagerImpl_OpenThread_LwIP; +#else + friend Internal::GenericThreadStackManagerImpl_OpenThread; +#endif friend Internal::GenericThreadStackManagerImpl_FreeRTOS; #endif @@ -66,6 +77,11 @@ class ThreadStackManagerImpl final : public ThreadStackManager, public: // ===== Platform-specific members that may be accessed directly by the application. +#if CHIP_DEVICE_CONFIG_PROCESS_BLE_IN_THREAD + using ThreadStackManager::ProcessThreadActivity; + void ProcessThreadActivity(); +#endif + protected: // ===== Methods that implement the ThreadStackManager abstract interface. CHIP_ERROR _InitThreadStack(void); diff --git a/src/platform/silabs/KeyValueStoreManagerImpl.cpp b/src/platform/silabs/KeyValueStoreManagerImpl.cpp index 8f886dba84ba67..012c951aaaa729 100644 --- a/src/platform/silabs/KeyValueStoreManagerImpl.cpp +++ b/src/platform/silabs/KeyValueStoreManagerImpl.cpp @@ -164,15 +164,9 @@ void KeyValueStoreManagerImpl::ScheduleKeyMapSave(void) During commissioning, the key map will be modified multiples times subsequently. Commit the key map in nvm once it as stabilized. */ -#if SLI_SI91X_MCU_INTERFACE && CHIP_CONFIG_ENABLE_ICD_SERVER - // TODO: Remove this when RTC timer is added MATTER-2705 - SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_KvsStringKeyMap, reinterpret_cast(mKvsKeyMap), - sizeof(mKvsKeyMap)); -#else SystemLayer().StartTimer( std::chrono::duration_cast(System::Clock::Seconds32(SILABS_KVS_SAVE_DELAY_SECONDS)), KeyValueStoreManagerImpl::OnScheduledKeyMapSave, NULL); -#endif // defined(SLI_SI91X_MCU_INTERFACE) && CHIP_CONFIG_ENABLE_ICD_SERVER } CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, diff --git a/src/platform/silabs/SiWx917/wifi/wfx_host_events.h b/src/platform/silabs/SiWx917/wifi/wfx_host_events.h index e3f923894c24e6..745de9b38410ba 100644 --- a/src/platform/silabs/SiWx917/wifi/wfx_host_events.h +++ b/src/platform/silabs/SiWx917/wifi/wfx_host_events.h @@ -41,7 +41,10 @@ #define SL_WFX_CONNECT_IND_ID (2) #define SL_WFX_DISCONNECT_IND_ID (3) #define SL_WFX_SCAN_COMPLETE_ID (4) -#define WFX_RSI_SSID_SIZE (64) +// MAX SSID LENGTH excluding NULL character +#define WFX_MAX_SSID_LENGTH (32) +// MAX PASSKEY LENGTH including NULL character +#define WFX_MAX_PASSKEY_LENGTH (SL_WIFI_MAX_PSK_LENGTH) /* Wi-Fi bitmask events - for the task */ #define SL_WFX_CONNECT (1 << 1) @@ -55,6 +58,7 @@ #define WLAN_TASK_STACK_SIZE (1024) #define WLAN_TASK_PRIORITY (3) #define WLAN_DRIVER_TASK_PRIORITY (2) +#define BLE_DRIVER_TASK_PRIORITY (2) #define MAX_JOIN_RETRIES_COUNT (5) // WLAN retry time intervals in milli seconds @@ -66,7 +70,7 @@ // WLAN related Macros #define ETH_FRAME (0) #define CMP_SUCCESS (0) -#define BSSID_MAX_STR_LEN (6) +#define BSSID_LEN (6) #define MAC_ADDRESS_FIRST_OCTET (6) #define AP_START_SUCCESS (0) #define BITS_TO_WAIT (0) @@ -159,8 +163,8 @@ typedef enum typedef struct { - char ssid[32 + 1]; - char passkey[64 + 1]; + char ssid[WFX_MAX_SSID_LENGTH + 1]; + char passkey[WFX_MAX_PASSKEY_LENGTH + 1]; wfx_sec_t security; } wfx_wifi_provision_t; @@ -175,9 +179,9 @@ typedef enum typedef struct wfx_wifi_scan_result { - char ssid[32 + 1]; + char ssid[WFX_MAX_SSID_LENGTH + 1]; wfx_sec_t security; - uint8_t bssid[6]; + uint8_t bssid[BSSID_LEN]; uint8_t chan; int16_t rssi; /* I suspect this is in dBm - so signed */ } wfx_wifi_scan_result_t; diff --git a/src/platform/silabs/efr32/wifi/wfx_host_events.h b/src/platform/silabs/efr32/wifi/wfx_host_events.h index a7a2dc2ac34fa4..3e83f3b07d46c5 100644 --- a/src/platform/silabs/efr32/wifi/wfx_host_events.h +++ b/src/platform/silabs/efr32/wifi/wfx_host_events.h @@ -114,8 +114,6 @@ typedef struct __attribute__((__packed__)) sl_wfx_mib_req_s #define SL_WFX_CONNECT_IND_ID 2 #define SL_WFX_DISCONNECT_IND_ID 3 #define SL_WFX_SCAN_COMPLETE_ID 4 -#define WFX_RSI_SSID_SIZE 64 - #endif /* WF200 */ /* LwIP includes. */ @@ -141,14 +139,19 @@ typedef struct __attribute__((__packed__)) sl_wfx_mib_req_s #define WLAN_TASK_STACK_SIZE 1024 #define WLAN_TASK_PRIORITY 1 #define WLAN_DRIVER_TASK_PRIORITY 1 +#define BLE_DRIVER_TASK_PRIORITY 1 #define MAX_JOIN_RETRIES_COUNT 5 #else /* WF200 */ #define WLAN_TASK_STACK_SIZE 1024 #define WLAN_TASK_PRIORITY 1 -#define BLE_TASK_PRIORITY 1 #define MAX_JOIN_RETRIES_COUNT 5 -#endif +#endif // RS911X_WIFI + +// MAX SSID LENGTH excluding NULL character +#define WFX_MAX_SSID_LENGTH (32) +// MAX PASSKEY LENGTH including NULL character +#define WFX_MAX_PASSKEY_LENGTH (64) // WLAN retry time intervals in milli seconds #define WLAN_MAX_RETRY_TIMER_MS 30000 @@ -159,7 +162,7 @@ typedef struct __attribute__((__packed__)) sl_wfx_mib_req_s // WLAN related Macros #define ETH_FRAME 0 #define CMP_SUCCESS 0 -#define BSSID_MAX_STR_LEN 6 +#define BSSID_LEN (6) #define MAC_ADDRESS_FIRST_OCTET 6 #define AP_START_SUCCESS 0 #define BITS_TO_WAIT 0 @@ -254,8 +257,8 @@ typedef enum typedef struct { - char ssid[32 + 1]; - char passkey[64 + 1]; + char ssid[WFX_MAX_SSID_LENGTH + 1]; + char passkey[WFX_MAX_PASSKEY_LENGTH + 1]; wfx_sec_t security; } wfx_wifi_provision_t; @@ -270,9 +273,9 @@ typedef enum typedef struct wfx_wifi_scan_result { - char ssid[32 + 1]; + char ssid[WFX_MAX_SSID_LENGTH + 1]; wfx_sec_t security; - uint8_t bssid[6]; + uint8_t bssid[BSSID_LEN]; uint8_t chan; int16_t rssi; /* I suspect this is in dBm - so signed */ } wfx_wifi_scan_result_t; diff --git a/src/platform/silabs/rs911x/BLEManagerImpl.cpp b/src/platform/silabs/rs911x/BLEManagerImpl.cpp index 962c78fb9d3daa..bce62e75e7a3d9 100644 --- a/src/platform/silabs/rs911x/BLEManagerImpl.cpp +++ b/src/platform/silabs/rs911x/BLEManagerImpl.cpp @@ -253,8 +253,8 @@ CHIP_ERROR BLEManagerImpl::_Init() sl_rs_ble_init_sem = osSemaphoreNew(1, 0, NULL); sl_ble_event_sem = osSemaphoreNew(1, 0, NULL); - wfx_rsi.ble_task = xTaskCreateStatic((TaskFunction_t) sl_ble_event_handling_task, "rsi_ble", WFX_RSI_TASK_SZ, NULL, 1, - wfxBLETaskStack, &rsiBLETaskStruct); + wfx_rsi.ble_task = xTaskCreateStatic((TaskFunction_t) sl_ble_event_handling_task, "rsi_ble", WFX_RSI_TASK_SZ, NULL, + BLE_DRIVER_TASK_PRIORITY, wfxBLETaskStack, &rsiBLETaskStruct); if (wfx_rsi.ble_task == NULL) { @@ -419,7 +419,6 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) case DeviceEventType::kCHIPoBLEIndicateConfirm: { ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEIndicateConfirm"); - DeviceLayer::SystemLayer().CancelTimer(OnSendIndicationTimeout, this); HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_2_UUID); } break; @@ -924,6 +923,10 @@ void BLEManagerImpl::HandleRXCharWrite(rsi_ble_event_write_t * evt) void BLEManagerImpl::HandleTxConfirmationEvent(BLE_CONNECTION_OBJECT conId) { + DeviceLayer::PlatformMgr().LockChipStack(); + // stop the indication confirmation timer + DeviceLayer::SystemLayer().CancelTimer(OnSendIndicationTimeout, this); + DeviceLayer::PlatformMgr().UnlockChipStack(); ChipDeviceEvent event; event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; event.CHIPoBLEIndicateConfirm.ConId = conId; diff --git a/src/protocols/secure_channel/CASESession.cpp b/src/protocols/secure_channel/CASESession.cpp index b7aa87e9d5e278..96cd7e17eef449 100644 --- a/src/protocols/secure_channel/CASESession.cpp +++ b/src/protocols/secure_channel/CASESession.cpp @@ -599,7 +599,7 @@ void CASESession::OnResponseTimeout(ExchangeContext * ec) ChipLogError(SecureChannel, "CASESession::OnResponseTimeout exchange doesn't match")); ChipLogError(SecureChannel, "CASESession timed out while waiting for a response from peer " ChipLogFormatScopedNodeId ". Current state was %u", - ChipLogValueScopedNodeId(ScopedNodeId(mPeerNodeId, mFabricIndex)), to_underlying(mState)); + ChipLogValueScopedNodeId(GetPeer()), to_underlying(mState)); MATTER_TRACE_COUNTER("CASETimeout"); // Discard the exchange so that Clear() doesn't try aborting it. The // exchange will handle that. @@ -872,7 +872,7 @@ CHIP_ERROR CASESession::SendSigma1() mState = State::kSentSigma1; } - ChipLogProgress(SecureChannel, "Sent Sigma1 msg"); + ChipLogProgress(SecureChannel, "Sent Sigma1 msg to " ChipLogFormatScopedNodeId, ChipLogValueScopedNodeId(GetPeer())); mDelegate->OnSessionEstablishmentStarted(); diff --git a/src/protocols/secure_channel/tests/TestCASESession.cpp b/src/protocols/secure_channel/tests/TestCASESession.cpp index 24aaffce0dbcb4..aafda3c548fce7 100644 --- a/src/protocols/secure_channel/tests/TestCASESession.cpp +++ b/src/protocols/secure_channel/tests/TestCASESession.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -39,6 +38,7 @@ #include #include #include +#include #include #include "credentials/tests/CHIPCert_test_vectors.h" @@ -56,7 +56,7 @@ using namespace chip::Crypto; namespace chip { class TestCASESecurePairingDelegate; -class TestCASESession : public Test::LoopbackMessagingContext, public ::testing::Test +class TestCASESession : public Test::LoopbackMessagingContext { public: // Performs shared setup for all tests in the test suite @@ -70,8 +70,6 @@ class TestCASESession : public Test::LoopbackMessagingContext, public ::testing: chip::Test::LoopbackMessagingContext::SetUp(); } - virtual void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } - void ServiceEvents(); void SecurePairingHandshakeTestCommon(SessionManager & sessionManager, CASESession & pairingCommissioner, TestCASESecurePairingDelegate & delegateCommissioner); diff --git a/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp b/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp index 41b6539ecf0773..edd0bf5f3aa68d 100644 --- a/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp +++ b/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp @@ -34,8 +34,8 @@ #include #include -#include #include +#include #include @@ -64,14 +64,7 @@ class MockAppDelegate : public ExchangeDelegate int ReceiveHandlerCallCount = 0; }; -struct TestMessageCounterManager : public chip::Test::LoopbackMessagingContext, public ::testing::Test -{ - static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); } - static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); } - - void SetUp() override { chip::Test::LoopbackMessagingContext::SetUp(); } - void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } -}; +using TestMessageCounterManager = chip::Test::LoopbackMessagingContext; TEST_F(TestMessageCounterManager, MessageCounterSyncProcess) { diff --git a/src/protocols/secure_channel/tests/TestPASESession.cpp b/src/protocols/secure_channel/tests/TestPASESession.cpp index 5b3f957d51bf84..2d054821728379 100644 --- a/src/protocols/secure_channel/tests/TestPASESession.cpp +++ b/src/protocols/secure_channel/tests/TestPASESession.cpp @@ -22,7 +22,7 @@ */ #include -#include +#include #include #include @@ -84,21 +84,15 @@ constexpr Spake2pVerifierSerialized sTestSpake2p01_SerializedVerifier = { }; class TestSecurePairingDelegate; -class TestPASESession : public chip::Test::LoopbackMessagingContext, public ::testing::Test +class TestPASESession : public chip::Test::LoopbackMessagingContext { public: - // Performs shared setup for all tests in the test suite - static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); } - static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); } - void SetUp() override { ConfigInitializeNodes(false); chip::Test::LoopbackMessagingContext::SetUp(); } - void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } - void SecurePairingHandshakeTestCommon(SessionManager & sessionManager, PASESession & pairingCommissioner, Optional mrpCommissionerConfig, Optional mrpAccessoryConfig, diff --git a/src/python_testing/TC_EEM_2_1.py b/src/python_testing/TC_EEM_2_1.py index 51e01a1e4b3980..1e975a8e681f7d 100644 --- a/src/python_testing/TC_EEM_2_1.py +++ b/src/python_testing/TC_EEM_2_1.py @@ -44,13 +44,20 @@ def pics_TC_EEM_2_1(self): def steps_TC_EEM_2_1(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads Accuracy attribute. Verify that the DUT response contains a MeasurementAccuracyStruct value."), - TestStep("3", "TH reads CumulativeEnergyImported attribute. Verify that the DUT response contains either null or an EnergyMeasurementStruct value."), - TestStep("4", "TH reads CumulativeEnergyExported attribute. Verify that the DUT response contains either null or an EnergyMeasurementStruct value."), - TestStep("5", "TH reads PeriodicEnergyImported attribute. Verify that the DUT response contains either null or an EnergyMeasurementStruct value."), - TestStep("6", "TH reads PeriodicEnergyExported attribute. Verify that the DUT response contains either null or an EnergyMeasurementStruct value."), - TestStep("7", "TH reads CumulativeEnergyReset attribute. Verify that the DUT response contains either null or an CumulativeEnergyResetStruct value."), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads Accuracy attribute", + "Verify that the DUT response contains a MeasurementAccuracyStruct value."), + TestStep("3", "TH reads CumulativeEnergyImported attribute", + "Verify that the DUT response contains either null or an EnergyMeasurementStruct value."), + TestStep("4", "TH reads CumulativeEnergyExported attribute", + "Verify that the DUT response contains either null or an EnergyMeasurementStruct value."), + TestStep("5", "TH reads PeriodicEnergyImported attribute", + "Verify that the DUT response contains either null or an EnergyMeasurementStruct value."), + TestStep("6", "TH reads PeriodicEnergyExported attribute", + "Verify that the DUT response contains either null or an EnergyMeasurementStruct value."), + TestStep("7", "TH reads CumulativeEnergyReset attribute", + "Verify that the DUT response contains either null or an CumulativeEnergyResetStruct value."), ] return steps @@ -64,29 +71,34 @@ async def test_TC_EEM_2_1(self): self.step("2") accuracy = await self.read_eem_attribute_expect_success("Accuracy") logger.info(f"Rx'd Accuracy: {accuracy}") - asserts.assert_not_equal(accuracy, NullValue, "Accuracy is not allowed to be null") + asserts.assert_not_equal( + accuracy, NullValue, "Accuracy is not allowed to be null") asserts.assert_equal(accuracy.measurementType, Clusters.ElectricalEnergyMeasurement.Enums.MeasurementTypeEnum.kElectricalEnergy, "Accuracy measurementType must be ElectricalEnergy") self.step("3") if self.pics_guard(self.check_pics("EEM.S.A0001")): cumulativeEnergyImported = await self.read_eem_attribute_expect_success("CumulativeEnergyImported") - logger.info(f"Rx'd CumulativeEnergyImported: {cumulativeEnergyImported}") + logger.info( + f"Rx'd CumulativeEnergyImported: {cumulativeEnergyImported}") self.step("4") if self.pics_guard(self.check_pics("EEM.S.A0002")): cumulativeEnergyExported = await self.read_eem_attribute_expect_success("CumulativeEnergyExported") - logger.info(f"Rx'd CumulativeEnergyExported: {cumulativeEnergyExported}") + logger.info( + f"Rx'd CumulativeEnergyExported: {cumulativeEnergyExported}") self.step("5") if self.pics_guard(self.check_pics("EEM.S.A0003")): periodicEnergyImported = await self.read_eem_attribute_expect_success("PeriodicEnergyImported") - logger.info(f"Rx'd PeriodicEnergyImported: {periodicEnergyImported}") + logger.info( + f"Rx'd PeriodicEnergyImported: {periodicEnergyImported}") self.step("6") if self.pics_guard(self.check_pics("EEM.S.A0004")): periodicEnergyExported = await self.read_eem_attribute_expect_success("PeriodicEnergyExported") - logger.info(f"Rx'd PeriodicEnergyExported: {periodicEnergyExported}") + logger.info( + f"Rx'd PeriodicEnergyExported: {periodicEnergyExported}") self.step("7") if self.pics_guard(self.check_pics("EEM.S.A0005")): diff --git a/src/python_testing/TC_EEM_2_2.py b/src/python_testing/TC_EEM_2_2.py index 6571b80b53898d..d44821c6cd2209 100644 --- a/src/python_testing/TC_EEM_2_2.py +++ b/src/python_testing/TC_EEM_2_2.py @@ -40,13 +40,17 @@ def pics_TC_EEM_2_2(self): def steps_TC_EEM_2_2(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Start Fake Load Test 1kW Event"), TestStep("4", "Wait 3 seconds"), - TestStep("4a", "TH reads from the DUT the CumulativeEnergyImported attribute. Verify the read is successful and note the value read."), - TestStep("5", "Wait 3 seconds"), - TestStep("5a", "TH reads from the DUT the CumulativeEnergyImported attribute. Verify the read is successful and that the value is greater than the value measured in step 4a."), + TestStep("4a", "TH reads from the DUT the CumulativeEnergyImported attribute", + "Verify the read is successful and note the value read."), + TestStep("5", "Wait 5 seconds"), + TestStep("5a", "TH reads from the DUT the CumulativeEnergyImported attribute", + "Verify the read is successful and that the value is greater than the value measured in step 4a."), TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Stop Fake Readings Test Event."), ] @@ -71,7 +75,7 @@ async def test_TC_EEM_2_2(self): cumulative_energy_imported = await self.read_eem_attribute_expect_success("CumulativeEnergyImported") self.step("5") - time.sleep(3) + time.sleep(5) self.step("5a") cumulative_energy_imported_2 = await self.read_eem_attribute_expect_success("CumulativeEnergyImported") diff --git a/src/python_testing/TC_EEM_2_3.py b/src/python_testing/TC_EEM_2_3.py index 7842f46d02e86f..49149dff4a9b70 100644 --- a/src/python_testing/TC_EEM_2_3.py +++ b/src/python_testing/TC_EEM_2_3.py @@ -40,13 +40,17 @@ def pics_TC_EEM_2_3(self): def steps_TC_EEM_2_3(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Start Fake Generator Test 3kW Event"), TestStep("4", "Wait 6 seconds"), - TestStep("4a", "TH reads from the DUT the CumulativeEnergyExported attribute. Verify the read is successful and note the value read."), - TestStep("5", "Wait 6 seconds"), - TestStep("5a", "TH reads from the DUT the CumulativeEnergyExported attribute. Verify the read is successful and that the value is greater than the value measured in step 4a."), + TestStep("4a", "TH reads from the DUT the CumulativeEnergyExported attribute", + "Verify the read is successful and note the value read."), + TestStep("5", "Wait 11 seconds"), + TestStep("5a", "TH reads from the DUT the CumulativeEnergyExported attribute", + "Verify the read is successful and that the value is greater than the value measured in step 4a."), TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Stop Fake Readings Test Event."), ] @@ -71,7 +75,7 @@ async def test_TC_EEM_2_3(self): cumulative_energy_exported = await self.read_eem_attribute_expect_success("CumulativeEnergyExported") self.step("5") - time.sleep(6) + time.sleep(11) self.step("5a") cumulative_energy_exported_2 = await self.read_eem_attribute_expect_success("CumulativeEnergyExported") diff --git a/src/python_testing/TC_EEM_2_4.py b/src/python_testing/TC_EEM_2_4.py index 2cf3b3482122e6..94cf7bd3670543 100644 --- a/src/python_testing/TC_EEM_2_4.py +++ b/src/python_testing/TC_EEM_2_4.py @@ -40,13 +40,17 @@ def pics_TC_EEM_2_4(self): def steps_TC_EEM_2_4(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Start Fake Load Test 1kW Event"), TestStep("4", "Wait 3 seconds"), - TestStep("4a", "TH reads from the DUT the PeriodicEnergyImported attribute. Verify the read is successful and note the value read."), - TestStep("5", "Wait 3 seconds"), - TestStep("5a", "TH reads from the DUT the PeriodicEnergyImported attribute. Verify the read is successful and that the value read has to be different from value measure in step 4a."), + TestStep("4a", "TH reads from the DUT the PeriodicEnergyImported attribute", + "Verify the read is successful and note the value read."), + TestStep("5", "Wait 5 seconds"), + TestStep("5a", "TH reads from the DUT the PeriodicEnergyImported attribute", + "Verify the read is successful and that the value read has to be different from value measure in step 4a."), TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Stop Fake Readings Test Event."), ] @@ -71,7 +75,7 @@ async def test_TC_EEM_2_4(self): periodic_energy_imported = await self.read_eem_attribute_expect_success("PeriodicEnergyImported") self.step("5") - time.sleep(3) + time.sleep(5) self.step("5a") periodic_energy_imported_2 = await self.read_eem_attribute_expect_success("PeriodicEnergyImported") diff --git a/src/python_testing/TC_EEM_2_5.py b/src/python_testing/TC_EEM_2_5.py index 6a45707bf936ed..7a42913956ca19 100644 --- a/src/python_testing/TC_EEM_2_5.py +++ b/src/python_testing/TC_EEM_2_5.py @@ -40,13 +40,17 @@ def pics_TC_EEM_2_5(self): def steps_TC_EEM_2_5(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Start Fake Generator Test 3kW Event"), TestStep("4", "Wait 6 seconds"), - TestStep("4a", "TH reads from the DUT the PeriodicEnergyExported attribute. Verify the read is successful and note the value read."), - TestStep("5", "Wait 6 seconds"), - TestStep("5a", "TH reads from the DUT the PeriodicEnergyExported attribute. Verify the read is successful and that the value read has to be different from value measure in step 4a."), + TestStep("4a", "TH reads from the DUT the PeriodicEnergyExported attribute", + "Verify the read is successful and note the value read."), + TestStep("5", "Wait 11 seconds"), + TestStep("5a", "TH reads from the DUT the PeriodicEnergyExported attribute", + "Verify the read is successful and that the value read has to be different from value measure in step 4a."), TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Stop Fake Readings Test Event."), ] @@ -71,7 +75,7 @@ async def test_TC_EEM_2_5(self): periodic_energy_exported = await self.read_eem_attribute_expect_success("PeriodicEnergyExported") self.step("5") - time.sleep(6) + time.sleep(11) self.step("5a") periodic_energy_exported_2 = await self.read_eem_attribute_expect_success("PeriodicEnergyExported") diff --git a/src/python_testing/TC_EEVSE_2_2.py b/src/python_testing/TC_EEVSE_2_2.py index 4fdf12c151069a..6c41f4e684e8ea 100644 --- a/src/python_testing/TC_EEVSE_2_2.py +++ b/src/python_testing/TC_EEVSE_2_2.py @@ -47,51 +47,92 @@ def pics_TC_EEVSE_2_2(self): def steps_TC_EEVSE_2_2(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event"), - TestStep("3a", "After a few seconds TH reads from the DUT the State attribute. Verify value is 0x00 (NotPluggedIn)"), - TestStep("3b", "TH reads from the DUT the SupplyState attribute. Verify value is 0x00 (Disabled)"), - TestStep("3c", "TH reads from the DUT the FaultState attribute. Verify value is 0x00 (NoError)"), - TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event. Verify Event EEVSE.S.E00(EVConnected) sent"), - TestStep("4a", "TH reads from the DUT the State attribute. Verify value is 0x01 (PluggedInNoDemand)"), - TestStep("4b", "TH reads from the DUT the SessionID attribute. Value is noted for later"), + TestStep("3a", "After a few seconds TH reads from the DUT the State attribute.", + "Verify value is 0x00 (NotPluggedIn)"), + TestStep("3b", "TH reads from the DUT the SupplyState attribute.", + "Verify value is 0x00 (Disabled)"), + TestStep("3c", "TH reads from the DUT the FaultState attribute.", + "Verify value is 0x00 (NoError)"), + TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event.", + "Verify Event EEVSE.S.E00(EVConnected) sent"), + TestStep("4a", "TH reads from the DUT the State attribute.", + "Verify value is 0x01 (PluggedInNoDemand)"), + TestStep("4b", + "TH reads from the DUT the SessionID attribute. Value is noted for later"), TestStep("5", "TH sends command EnableCharging with ChargingEnabledUntil=2 minutes in the future, minimumChargeCurrent=6000, maximumChargeCurrent=60000"), - TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event. Verify Event EEVSE.S.E02(EnergyTransferStarted) sent."), - TestStep("6a", "TH reads from the DUT the State attribute. Verify value is 0x3 (PluggedInCharging)"), - TestStep("6b", "TH reads from the DUT the SupplyState attribute. Verify value is 0x1 (ChargingEnabled)"), - TestStep("6c", "TH reads from the DUT the ChargingEnabledUntil attribute. Verify value is the commanded value"), - TestStep("6d", "TH reads from the DUT the MinimumChargeCurrent attribute. Verify value is the commanded value (6000)"), - TestStep("6e", "TH reads from the DUT the MaximumChargeCurrent attribute. Verify value is the min(command value (60000), CircuitCapacity)"), - TestStep("7", "Wait 2 minutes. Verify Event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvseStopped"), - TestStep("7a", "TH reads from the DUT the State attribute. Verify value is 0x02 (PluggedInDemand)"), - TestStep("7b", "TH reads from the DUT the SupplyState attribute. Verify value is 0x00 (Disabled)"), + TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event.", + "Verify Event EEVSE.S.E02(EnergyTransferStarted) sent."), + TestStep("6a", "TH reads from the DUT the State attribute.", + "Verify value is 0x3 (PluggedInCharging)"), + TestStep("6b", "TH reads from the DUT the SupplyState attribute.", + "Verify value is 0x1 (ChargingEnabled)"), + TestStep("6c", "TH reads from the DUT the ChargingEnabledUntil attribute.", + "Verify value is the commanded value"), + TestStep("6d", "TH reads from the DUT the MinimumChargeCurrent attribute.", + "Verify value is the commanded value (6000)"), + TestStep("6e", "TH reads from the DUT the MaximumChargeCurrent attribute.", + "Verify value is the min(command value (60000), CircuitCapacity)"), + TestStep("7", "Wait 2 minutes.", + "Verify Event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvseStopped"), + TestStep("7a", "TH reads from the DUT the State attribute.", + "Verify value is 0x02 (PluggedInDemand)"), + TestStep("7b", "TH reads from the DUT the SupplyState attribute.", + "Verify value is 0x00 (Disabled)"), TestStep("8", "TH sends command EnableCharging with ChargingEnabledUntil=NULL, minimumChargeCurrent = 6000, maximumChargeCurrent=12000"), - TestStep("8a", "TH reads from the DUT the State attribute. Verify value is 0x03 (PluggedInCharging)"), - TestStep("8b", "TH reads from the DUT the SupplyState attribute. Verify value is 1 (ChargingEnabled)"), - TestStep("8c", "TH reads from the DUT the ChargingEnabledUntil attribute. Verify value is the commanded value (NULL)"), - TestStep("8d", "TH reads from the DUT the MinimumChargeCurrent attribute. Verify value is the commanded value (6000)"), - TestStep("8e", "TH reads from the DUT the MaximumChargeCurrent attribute. Verify value is the MIN(command value (60000), CircuitCapacity)"), - TestStep("9", "If the optional attribute is supported TH writes to the DUT UserMaximumChargeCurrent=6000"), - TestStep("9a", "After a few seconds TH reads from the DUT the MaximumChargeCurrent. Verify value is UserMaximumChargeCurrent value (6000)"), - TestStep("10", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event Clear. Verify Event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvStopped"), - TestStep("10a", "TH reads from the DUT the State attribute. Verify value is 0x01 (PluggedInNoDemand)"), - TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event. Verify Event EEVSE.S.E02(EnergyTransferStarted) sent."), - TestStep("11a", "TH reads from the DUT the State attribute. Verify value is 0x03 (PluggedInCharging)"), - TestStep("12", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event Clear. Verify Event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvStopped"), - TestStep("12a", "TH reads from the DUT the State attribute. Verify value is 0x01 (PluggedInNoDemand)"), - TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event Clear. Verify Event EEVSE.S.E01(EVNotDetected) sent"), - TestStep("13a", "TH reads from the DUT the State attribute. Verify value is 0x00 (NotPluggedIn)"), - TestStep("13b", "TH reads from the DUT the SupplyState attribute. Verify value is 0x01 (ChargingEnabled)"), - TestStep("13c", "TH reads from the DUT the SessionID attribute. Verify value is the same value noted in 4b"), - TestStep("13d", "TH reads from the DUT the SessionDuration attribute. Verify value is greater than 120 (and match the time taken for the tests from step 4 to step 13)"), - TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event. Verify Event EEVSE.S.E00(EVConnected) sent"), - TestStep("14a", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event. Verify Event EEVSE.S.E02(EnergyTransferStarted) sent."), - TestStep("14b", "TH reads from the DUT the SessionID attribute. Verify value is 1 more than the value noted in 4b"), - TestStep("15", "TH sends command Disable. Verify Event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvseStopped"), - TestStep("15a", "TH reads from the DUT the SupplyState attribute. Verify value is 0x00 (Disabled)"), + TestStep("8a", "TH reads from the DUT the State attribute.", + "Verify value is 0x03 (PluggedInCharging)"), + TestStep("8b", "TH reads from the DUT the SupplyState attribute.", + "Verify value is 1 (ChargingEnabled)"), + TestStep("8c", "TH reads from the DUT the ChargingEnabledUntil attribute", + "Verify value is the commanded value (NULL)"), + TestStep("8d", "TH reads from the DUT the MinimumChargeCurrent attribute", + "Verify value is the commanded value (6000)"), + TestStep("8e", "TH reads from the DUT the MaximumChargeCurrent attribute", + "Verify value is the MIN(command value (60000), CircuitCapacity)"), + TestStep("9", + "If the optional attribute is supported TH writes to the DUT UserMaximumChargeCurrent=6000"), + TestStep("9a", "After a few seconds TH reads from the DUT the MaximumChargeCurrent", + "Verify value is UserMaximumChargeCurrent value (6000)"), + TestStep("10", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event Clear", + "Verify Event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvStopped"), + TestStep("10a", "TH reads from the DUT the State attribute", + "Verify value is 0x01 (PluggedInNoDemand)"), + TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event", + "Verify Event EEVSE.S.E02(EnergyTransferStarted) sent."), + TestStep("11a", "TH reads from the DUT the State attribute", + "Verify value is 0x03 (PluggedInCharging)"), + TestStep("12", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event Clear", + "Verify Event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvStopped"), + TestStep("12a", "TH reads from the DUT the State attribute", + "Verify value is 0x01 (PluggedInNoDemand)"), + TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event Clear", + "Verify Event EEVSE.S.E01(EVNotDetected) sent"), + TestStep("13a", "TH reads from the DUT the State attribute", + "Verify value is 0x00 (NotPluggedIn)"), + TestStep("13b", "TH reads from the DUT the SupplyState attribute", + "Verify value is 0x01 (ChargingEnabled)"), + TestStep("13c", "TH reads from the DUT the SessionID attribute", + "Verify value is the same value noted in 4b"), + TestStep("13d", "TH reads from the DUT the SessionDuration attribute", + "Verify value is greater than 120 (and match the time taken for the tests from step 4 to step 13)"), + TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event", + "Verify Event EEVSE.S.E00(EVConnected) sent"), + TestStep("14a", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event", + "Verify Event EEVSE.S.E02(EnergyTransferStarted) sent."), + TestStep("14b", "TH reads from the DUT the SessionID attribute", + "Verify value is 1 more than the value noted in 4b"), + TestStep("15", "TH sends command Disable", + "Verify Event EEVSE.S.E03(EnergyTransferStopped) sent with reason EvseStopped"), + TestStep("15a", "TH reads from the DUT the SupplyState attribute", + "Verify value is 0x00 (Disabled)"), TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event Clear."), - TestStep("17", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event Clear. Verify Event EEVSE.S.E01(EVNotDetected) sent"), + TestStep("17", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event Clear", + "Verify Event EEVSE.S.E01(EVNotDetected) sent"), TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event Clear."), ] @@ -129,7 +170,8 @@ async def test_TC_EEVSE_2_2(self): self.step("4") await self.send_test_event_trigger_pluggedin() - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EVConnected) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EVConnected) self.step("4a") await self.check_evse_attribute("State", Clusters.EnergyEvse.Enums.StateEnum.kPluggedInNoDemand) @@ -145,15 +187,18 @@ async def test_TC_EEVSE_2_2(self): max_charge_current = 60000 expected_state = Clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging # get epoch time for ChargeUntil variable (2 minutes from now) - utc_time_charging_end = datetime.now(tz=timezone.utc) + timedelta(seconds=charging_duration) + utc_time_charging_end = datetime.now( + tz=timezone.utc) + timedelta(seconds=charging_duration) # Matter epoch is 0 hours, 0 minutes, 0 seconds on Jan 1, 2000 UTC - epoch_time = int((utc_time_charging_end - datetime(2000, 1, 1, 0, 0, 0, 0, timezone.utc)).total_seconds()) + epoch_time = int((utc_time_charging_end - datetime(2000, + 1, 1, 0, 0, 0, 0, timezone.utc)).total_seconds()) await self.send_enable_charge_command(endpoint=1, charge_until=epoch_time, min_charge=min_charge_current, max_charge=max_charge_current) self.step("6") await self.send_test_event_trigger_charge_demand() - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EnergyTransferStarted) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EnergyTransferStarted) self.step("6a") await self.check_evse_attribute("State", expected_state) @@ -172,15 +217,18 @@ async def test_TC_EEVSE_2_2(self): expected_max_charge = min(max_charge_current, circuit_capacity) await self.check_evse_attribute("MaximumChargeCurrent", expected_max_charge) - self.validate_energy_transfer_started_event(event_data, session_id, expected_state, expected_max_charge) + self.validate_energy_transfer_started_event( + event_data, session_id, expected_state, expected_max_charge) self.step("7") # Sleep for the charging duration plus a couple of seconds to check it has stopped time.sleep(charging_duration + 2) # check EnergyTransferredStoped (EvseStopped) - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EnergyTransferStopped) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EnergyTransferStopped) expected_reason = Clusters.EnergyEvse.Enums.EnergyTransferStoppedReasonEnum.kEVSEStopped - self.validate_energy_transfer_stopped_event(event_data, session_id, expected_state, expected_reason) + self.validate_energy_transfer_stopped_event( + event_data, session_id, expected_state, expected_reason) self.step("7a") await self.check_evse_attribute("State", Clusters.EnergyEvse.Enums.StateEnum.kPluggedInDemand) @@ -194,7 +242,8 @@ async def test_TC_EEVSE_2_2(self): max_charge_current = 12000 await self.send_enable_charge_command(charge_until=charge_until, min_charge=min_charge_current, max_charge=max_charge_current) - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EnergyTransferStarted) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EnergyTransferStarted) self.step("8a") await self.check_evse_attribute("State", Clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging) @@ -214,7 +263,8 @@ async def test_TC_EEVSE_2_2(self): await self.check_evse_attribute("MaximumChargeCurrent", expected_max_charge) # from step 8 above - validate event - self.validate_energy_transfer_started_event(event_data, session_id, expected_state, expected_max_charge) + self.validate_energy_transfer_started_event( + event_data, session_id, expected_state, expected_max_charge) self.step("9") # This will only work if the optional UserMaximumChargeCurrent attribute is supported @@ -227,16 +277,20 @@ async def test_TC_EEVSE_2_2(self): self.step("9a") time.sleep(3) - expected_max_charge = min(user_max_charge_current, circuit_capacity) + expected_max_charge = min( + user_max_charge_current, circuit_capacity) await self.check_evse_attribute("MaximumChargeCurrent", expected_max_charge) else: - logging.info("UserMaximumChargeCurrent is NOT supported... skipping.") + logging.info( + "UserMaximumChargeCurrent is NOT supported... skipping.") self.step("10") await self.send_test_event_trigger_charge_demand_clear() - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EnergyTransferStopped) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EnergyTransferStopped) expected_reason = Clusters.EnergyEvse.Enums.EnergyTransferStoppedReasonEnum.kEVStopped - self.validate_energy_transfer_stopped_event(event_data, session_id, expected_state, expected_reason) + self.validate_energy_transfer_stopped_event( + event_data, session_id, expected_state, expected_reason) self.step("10a") await self.check_evse_attribute("State", Clusters.EnergyEvse.Enums.StateEnum.kPluggedInNoDemand) @@ -245,26 +299,32 @@ async def test_TC_EEVSE_2_2(self): await self.send_test_event_trigger_charge_demand() # Check we get EnergyTransferStarted again await self.send_enable_charge_command(charge_until=charge_until, min_charge=min_charge_current, max_charge=max_charge_current) - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EnergyTransferStarted) - self.validate_energy_transfer_started_event(event_data, session_id, expected_state, expected_max_charge) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EnergyTransferStarted) + self.validate_energy_transfer_started_event( + event_data, session_id, expected_state, expected_max_charge) self.step("11a") await self.check_evse_attribute("State", Clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging) self.step("12") await self.send_test_event_trigger_charge_demand_clear() - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EnergyTransferStopped) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EnergyTransferStopped) expected_reason = Clusters.EnergyEvse.Enums.EnergyTransferStoppedReasonEnum.kEVStopped - self.validate_energy_transfer_stopped_event(event_data, session_id, expected_state, expected_reason) + self.validate_energy_transfer_stopped_event( + event_data, session_id, expected_state, expected_reason) self.step("12a") await self.check_evse_attribute("State", Clusters.EnergyEvse.Enums.StateEnum.kPluggedInNoDemand) self.step("13") await self.send_test_event_trigger_pluggedin_clear() - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EVNotDetected) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EVNotDetected) expected_state = Clusters.EnergyEvse.Enums.StateEnum.kPluggedInNoDemand - self.validate_ev_not_detected_event(event_data, session_id, expected_state, expected_duration=0, expected_charged=0) + self.validate_ev_not_detected_event( + event_data, session_id, expected_state, expected_duration=0, expected_charged=0) self.step("13a") await self.check_evse_attribute("State", Clusters.EnergyEvse.Enums.StateEnum.kNotPluggedIn) @@ -286,24 +346,31 @@ async def test_TC_EEVSE_2_2(self): session_id = session_id + 1 # Check we get a new EVConnected event with updated session ID - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EVConnected) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EVConnected) self.validate_ev_connected_event(event_data, session_id) self.step("14a") await self.send_test_event_trigger_charge_demand() - expected_state = Clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging # This is the value at the event time - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EnergyTransferStarted) - self.validate_energy_transfer_started_event(event_data, session_id, expected_state, expected_max_charge) + # This is the value at the event time + expected_state = Clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EnergyTransferStarted) + self.validate_energy_transfer_started_event( + event_data, session_id, expected_state, expected_max_charge) self.step("14b") await self.check_evse_attribute("SessionID", session_id) self.step("15") await self.send_disable_command() - expected_state = Clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging # This is the value prior to stopping - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EnergyTransferStopped) + # This is the value prior to stopping + expected_state = Clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EnergyTransferStopped) expected_reason = Clusters.EnergyEvse.Enums.EnergyTransferStoppedReasonEnum.kEVSEStopped - self.validate_energy_transfer_stopped_event(event_data, session_id, expected_state, expected_reason) + self.validate_energy_transfer_stopped_event( + event_data, session_id, expected_state, expected_reason) self.step("15a") await self.check_evse_attribute("SupplyState", Clusters.EnergyEvse.Enums.SupplyStateEnum.kDisabled) @@ -313,9 +380,11 @@ async def test_TC_EEVSE_2_2(self): self.step("17") await self.send_test_event_trigger_pluggedin_clear() - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EVNotDetected) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EVNotDetected) expected_state = Clusters.EnergyEvse.Enums.StateEnum.kPluggedInNoDemand - self.validate_ev_not_detected_event(event_data, session_id, expected_state, expected_duration=0, expected_charged=0) + self.validate_ev_not_detected_event( + event_data, session_id, expected_state, expected_duration=0, expected_charged=0) self.step("18") await self.send_test_event_trigger_basic_clear() diff --git a/src/python_testing/TC_EEVSE_2_4.py b/src/python_testing/TC_EEVSE_2_4.py index f8d88270de4a83..b2618f4e6035af 100644 --- a/src/python_testing/TC_EEVSE_2_4.py +++ b/src/python_testing/TC_EEVSE_2_4.py @@ -45,30 +45,51 @@ def pics_TC_EEVSE_2_4(self): def steps_TC_EEVSE_2_4(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event"), - TestStep("3a", "After a few seconds TH reads from the DUT the State attribute. Verify value is 0x00 (NotPluggedIn)"), - TestStep("3b", "TH reads from the DUT the SupplyState attribute. Verify value is 0x00 (Disabled)"), - TestStep("3c", "TH reads from the DUT the FaultState attribute. Verify value is 0x00 (NoError)"), - TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event. Verify Event EEVSE.S.E00(EVConnected) sent"), - TestStep("4a", "TH reads from the DUT the State attribute. Verify value is 0x01 (PluggedInNoDemand)"), - TestStep("4b", "TH reads from the DUT the SessionID attribute. Value is saved for later"), + TestStep("3a", "After a few seconds TH reads from the DUT the State attribute", + "Verify value is 0x00 (NotPluggedIn)"), + TestStep("3b", "TH reads from the DUT the SupplyState attribute", + "Verify value is 0x00 (Disabled)"), + TestStep("3c", "TH reads from the DUT the FaultState attribute", + "Verify value is 0x00 (NoError)"), + TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event", + "Verify Event EEVSE.S.E00(EVConnected) sent"), + TestStep("4a", "TH reads from the DUT the State attribute", + "Verify value is 0x01 (PluggedInNoDemand)"), + TestStep("4b", + "TH reads from the DUT the SessionID attribute. Value is saved for later"), TestStep("5", "TH sends command EnableCharging with ChargingEnabledUntil=Null, minimumChargeCurrent=6000, maximumChargeCurrent=60000"), - TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event. Verify Event EEVSE.S.E02(EnergyTransferStarted) sent."), - TestStep("6a", "TH reads from the DUT the State attribute. Verify value is 0x3 (PluggedInCharging)"), - TestStep("6b", "TH reads from the DUT the SupplyState attribute. Verify value is 0x1 (ChargingEnabled)"), - TestStep("7", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EVSE Ground Fault Test Event. Verify Event EEVSE.S.E04(Fault) sent with SessionID matching value in step 4b, FaultStatePreviousFaultState = 0x00 (NoError), FaultStateCurrentFaultState = 0x07 (GroundFault)"), - TestStep("7a", "TH reads from the DUT the State attribute. Verify value is 0x6 (Fault)"), - TestStep("7b", "TH reads from the DUT the SupplyState attribute. Verify value is 0x4 (DisabledError)"), - TestStep("8", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EVSE Over Temperature Fault Test Event. Verify Event EEVSE.S.E04(Fault) sent with SessionID matching value in step 4b, FaultStatePreviousFaultState = 0x07 (GroundFault), FaultStateCurrentFaultState = 0x0F (OverTemperature)"), - TestStep("8a", "TH reads from the DUT the State attribute. Verify value is 0x6 (Fault)"), - TestStep("8b", "TH reads from the DUT the SupplyState attribute. Verify value is 0x4 (DisabledError)"), - TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EVSE Fault Test Event Clear. Verify Event EEVSE.S.E04(Fault) sent with SessionID matching value in step 4b, FaultStatePreviousFaultState = 0x0F (OverTemperature), FaultStateCurrentFaultState = 0x00 (NoError)"), - TestStep("9a", "TH reads from the DUT the State attribute. Verify value is 0x3 (PluggedInCharging)"), - TestStep("9b", "TH reads from the DUT the SupplyState attribute. Verify value is 0x1 (ChargingEnabled)"), + TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event", + "Verify Event EEVSE.S.E02(EnergyTransferStarted) sent."), + TestStep("6a", "TH reads from the DUT the State attribute", + "Verify value is 0x3 (PluggedInCharging)"), + TestStep("6b", "TH reads from the DUT the SupplyState attribute", + "Verify value is 0x1 (ChargingEnabled)"), + TestStep("7", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EVSE Ground Fault Test Event", + "Verify Event EEVSE.S.E04(Fault) sent with SessionID matching value in step 4b, FaultStatePreviousFaultState = 0x00 (NoError), FaultStateCurrentFaultState = 0x07 (GroundFault)"), + TestStep("7a", "TH reads from the DUT the State attribute", + "Verify value is 0x6 (Fault)"), + TestStep("7b", "TH reads from the DUT the SupplyState attribute", + "Verify value is 0x4 (DisabledError)"), + TestStep("8", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EVSE Over Temperature Fault Test Event", + "Verify Event EEVSE.S.E04(Fault) sent with SessionID matching value in step 4b, FaultStatePreviousFaultState = 0x07 (GroundFault), FaultStateCurrentFaultState = 0x0F (OverTemperature)"), + TestStep("8a", "TH reads from the DUT the State attribute", + "Verify value is 0x6 (Fault)"), + TestStep("8b", "TH reads from the DUT the SupplyState attribute", + "Verify value is 0x4 (DisabledError)"), + TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EVSE Fault Test Event Clear", + "Verify Event EEVSE.S.E04(Fault) sent with SessionID matching value in step 4b, FaultStatePreviousFaultState = 0x0F (OverTemperature), FaultStateCurrentFaultState = 0x00 (NoError)"), + TestStep("9a", "TH reads from the DUT the State attribute", + "Verify value is 0x3 (PluggedInCharging)"), + TestStep("9b", "TH reads from the DUT the SupplyState attribute", + "Verify value is 0x1 (ChargingEnabled)"), TestStep("10", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Charge Demand Test Event Clear."), - TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event Clear. Verify Event EEVSE.S.E01(EVNotDetected) sent"), + TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event Clear", + "Verify Event EEVSE.S.E01(EVNotDetected) sent"), TestStep("12", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event Clear."), ] @@ -105,7 +126,8 @@ async def test_TC_EEVSE_2_4(self): self.step("4") await self.send_test_event_trigger_pluggedin() - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EVConnected) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EVConnected) self.step("4a") await self.check_evse_attribute("State", Clusters.EnergyEvse.Enums.StateEnum.kPluggedInNoDemand) @@ -123,7 +145,8 @@ async def test_TC_EEVSE_2_4(self): self.step("6") await self.send_test_event_trigger_charge_demand() - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EnergyTransferStarted) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EnergyTransferStarted) self.step("6a") await self.check_evse_attribute("State", Clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging) @@ -133,11 +156,13 @@ async def test_TC_EEVSE_2_4(self): self.step("7") await self.send_test_event_trigger_evse_ground_fault() - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.Fault) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.Fault) expected_state = Clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging previous_fault = Clusters.EnergyEvse.Enums.FaultStateEnum.kNoError current_fault = Clusters.EnergyEvse.Enums.FaultStateEnum.kGroundFault - self.validate_evse_fault_event(event_data, session_id, expected_state, previous_fault, current_fault) + self.validate_evse_fault_event( + event_data, session_id, expected_state, previous_fault, current_fault) self.step("7a") await self.check_evse_attribute("State", Clusters.EnergyEvse.Enums.StateEnum.kFault) @@ -147,11 +172,13 @@ async def test_TC_EEVSE_2_4(self): self.step("8") await self.send_test_event_trigger_evse_over_temperature_fault() - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.Fault) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.Fault) expected_state = Clusters.EnergyEvse.Enums.StateEnum.kFault previous_fault = Clusters.EnergyEvse.Enums.FaultStateEnum.kGroundFault current_fault = Clusters.EnergyEvse.Enums.FaultStateEnum.kOverTemperature - self.validate_evse_fault_event(event_data, session_id, expected_state, previous_fault, current_fault) + self.validate_evse_fault_event( + event_data, session_id, expected_state, previous_fault, current_fault) self.step("8a") await self.check_evse_attribute("State", Clusters.EnergyEvse.Enums.StateEnum.kFault) @@ -161,11 +188,13 @@ async def test_TC_EEVSE_2_4(self): self.step("9") await self.send_test_event_trigger_evse_fault_clear() - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.Fault) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.Fault) expected_state = Clusters.EnergyEvse.Enums.StateEnum.kFault previous_fault = Clusters.EnergyEvse.Enums.FaultStateEnum.kOverTemperature current_fault = Clusters.EnergyEvse.Enums.FaultStateEnum.kNoError - self.validate_evse_fault_event(event_data, session_id, expected_state, previous_fault, current_fault) + self.validate_evse_fault_event( + event_data, session_id, expected_state, previous_fault, current_fault) self.step("9a") await self.check_evse_attribute("State", Clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging) @@ -175,13 +204,16 @@ async def test_TC_EEVSE_2_4(self): self.step("10") await self.send_test_event_trigger_charge_demand_clear() - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EnergyTransferStopped) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EnergyTransferStopped) self.step("11") await self.send_test_event_trigger_pluggedin_clear() - event_data = events_callback.wait_for_event_report(Clusters.EnergyEvse.Events.EVNotDetected) + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EVNotDetected) expected_state = Clusters.EnergyEvse.Enums.StateEnum.kPluggedInNoDemand - self.validate_ev_not_detected_event(event_data, session_id, expected_state, expected_duration=0, expected_charged=0) + self.validate_ev_not_detected_event( + event_data, session_id, expected_state, expected_duration=0, expected_charged=0) self.step("12") await self.send_test_event_trigger_basic_clear() diff --git a/src/python_testing/TC_EEVSE_2_5.py b/src/python_testing/TC_EEVSE_2_5.py index 3fdb5f901b6f97..914a4a83d9c9a7 100644 --- a/src/python_testing/TC_EEVSE_2_5.py +++ b/src/python_testing/TC_EEVSE_2_5.py @@ -45,24 +45,38 @@ def pics_TC_EEVSE_2_5(self): def steps_TC_EEVSE_2_5(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event"), - TestStep("3a", "TH reads from the DUT the State attribute. Verify value is 0x00 (NotPluggedIn)"), - TestStep("3b", "TH reads from the DUT the SupplyState attribute. Verify value is 0x00 (Disabled)"), - TestStep("3c", "TH reads from the DUT the FaultState attribute. Verify value is 0x00 (NoError)"), + TestStep("3a", "TH reads from the DUT the State attribute", + "Verify value is 0x00 (NotPluggedIn)"), + TestStep("3b", "TH reads from the DUT the SupplyState attribute", + "Verify value is 0x00 (Disabled)"), + TestStep("3c", "TH reads from the DUT the FaultState attribute", + "Verify value is 0x00 (NoError)"), TestStep("4", "TH sends command EnableCharging with ChargingEnabledUntil=Null, minimumChargeCurrent=6000, maximumChargeCurrent=60000"), - TestStep("4a", "TH reads from the DUT the State attribute. Verify value is 0x00 (NotPluggedIn)"), - TestStep("4b", "TH reads from the DUT the SupplyState attribute. Verify value is 0x01 (ChargingEnabled)"), - TestStep("5", "TH sends command StartDiagnostics. Verify that command is rejected with Failure"), + TestStep("4a", "TH reads from the DUT the State attribute", + "Verify value is 0x00 (NotPluggedIn)"), + TestStep("4b", "TH reads from the DUT the SupplyState attribute", + "Verify value is 0x01 (ChargingEnabled)"), + TestStep("5", "TH sends command StartDiagnostics", + "Verify that command is rejected with Failure"), TestStep("6", "TH sends command Disable."), - TestStep("6a", "TH reads from the DUT the State attribute. Verify value is 0x00 (NotPluggedIn)"), - TestStep("6b", "TH reads from the DUT the SupplyState attribute. Verify value is 0x00 (Disabled)"), - TestStep("7", "TH sends command StartDiagnostics. Verify that command is accepted with Success"), - TestStep("7a", "TH reads from the DUT the SupplyState attribute. Verify value is 0x04 (DisabledDiagnostics)"), + TestStep("6a", "TH reads from the DUT the State attribute", + "Verify value is 0x00 (NotPluggedIn)"), + TestStep("6b", "TH reads from the DUT the SupplyState attribute", + "Verify value is 0x00 (Disabled)"), + TestStep("7", "TH sends command StartDiagnostics", + "Verify that command is accepted with Success"), + TestStep("7a", "TH reads from the DUT the SupplyState attribute", + "Verify value is 0x04 (DisabledDiagnostics)"), TestStep("8", "A few seconds later TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EVSE Diagnostics Complete Event"), - TestStep("8a", "TH reads from the DUT the State attribute. Verify value is 0x00 (NotPluggedIn)"), - TestStep("8b", "TH reads from the DUT the SupplyState attribute. Verify value is 0x00 (Disabled)"), + TestStep("8a", "TH reads from the DUT the State attribute", + "Verify value is 0x00 (NotPluggedIn)"), + TestStep("8b", "TH reads from the DUT the SupplyState attribute", + "Verify value is 0x00 (Disabled)"), TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event Clear."), ] diff --git a/src/python_testing/TC_EPM_2_1.py b/src/python_testing/TC_EPM_2_1.py index 2c39fd9aaa7d3f..c856fecf21fb9a 100644 --- a/src/python_testing/TC_EPM_2_1.py +++ b/src/python_testing/TC_EPM_2_1.py @@ -46,26 +46,48 @@ def pics_TC_EPM_2_1(self): def steps_TC_EPM_2_1(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads PowerMode attribute. Verify that the DUT response contains an enum8 value"), - TestStep("3", "TH reads NumberOfMeasurementTypes attribute. Verify that the DUT response contains an uint8 value."), - TestStep("4", "TH reads Accuracy attribute. Verify that the DUT response contains a list of MeasurementAccuracyStruct entries - Verify that the list has between 1 and NumberOfMeasurementTypes entries."), - TestStep("5", "TH reads Ranges attribute. Verify that the DUT response contains a list of MeasurementRangeStruct entries - Verify that the list has between 0 and NumberOfMeasurementTypes entries."), - TestStep("6", "TH reads Voltage attribute. Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), - TestStep("7", "TH reads ActiveCurrent attribute. Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), - TestStep("8", "TH reads ReactiveCurrent attribute. Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), - TestStep("9", "TH reads ApparentCurrent attribute. Verify that the DUT response contains either null or an int64 value. Value has to be between a range of 0 to 2^62."), - TestStep("10", "TH reads ActivePower attribute. Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), - TestStep("11", "TH reads ReactivePower attribute. Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), - TestStep("12", "TH reads ApparentPower attribute. Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), - TestStep("13", "TH reads RMSVoltage attribute. Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), - TestStep("14", "TH reads RMSCurrent attribute. Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), - TestStep("15", "TH reads RMSPower attribute. Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), - TestStep("16", "TH reads Frequency attribute. Verify that the DUT response contains either null or an int64 value. Value has to be between a range of 0 to 1000000."), - TestStep("17", "TH reads HarmonicCurrents attribute. Verify that the DUT response contains a list of HarmonicMeasurementStruct entries."), - TestStep("18", "TH reads HarmonicPhases attribute. Verify that the DUT response contains a list of HarmonicMeasurementStruct entries."), - TestStep("19", "TH reads PowerFactor attribute. Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -10000 to 10000."), - TestStep("20", "TH reads NeutralCurrent attribute. Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads PowerMode attribute", + "Verify that the DUT response contains an enum8 value"), + TestStep("3", "TH reads NumberOfMeasurementTypes attribute", + "Verify that the DUT response contains an uint8 value."), + TestStep("4", "TH reads Accuracy attribute", + "Verify that the DUT response contains a list of MeasurementAccuracyStruct entries ", + "Verify that the list has between 1 and NumberOfMeasurementTypes entries."), + TestStep("5", "TH reads Ranges attribute", + "Verify that the DUT response contains a list of MeasurementRangeStruct entries ", + "Verify that the list has between 0 and NumberOfMeasurementTypes entries."), + TestStep("6", "TH reads Voltage attribute", + "Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), + TestStep("7", "TH reads ActiveCurrent attribute", + "Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), + TestStep("8", "TH reads ReactiveCurrent attribute", + "Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), + TestStep("9", "TH reads ApparentCurrent attribute", + "Verify that the DUT response contains either null or an int64 value. Value has to be between a range of 0 to 2^62."), + TestStep("10", "TH reads ActivePower attribute", + "Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), + TestStep("11", "TH reads ReactivePower attribute", + "Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), + TestStep("12", "TH reads ApparentPower attribute", + "Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), + TestStep("13", "TH reads RMSVoltage attribute", + "Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), + TestStep("14", "TH reads RMSCurrent attribute", + "Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), + TestStep("15", "TH reads RMSPower attribute", + "Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), + TestStep("16", "TH reads Frequency attribute", + "Verify that the DUT response contains either null or an int64 value. Value has to be between a range of 0 to 1000000."), + TestStep("17", "TH reads HarmonicCurrents attribute", + "Verify that the DUT response contains a list of HarmonicMeasurementStruct entries."), + TestStep("18", "TH reads HarmonicPhases attribute", + "Verify that the DUT response contains a list of HarmonicMeasurementStruct entries."), + TestStep("19", "TH reads PowerFactor attribute", + "Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -10000 to 10000."), + TestStep("20", "TH reads NeutralCurrent attribute", + "Verify that the DUT response contains either null or an int64 value. Value has to be between a range of -2^62 to 2^62."), ] return steps @@ -109,7 +131,8 @@ async def test_TC_EPM_2_1(self): for index, range_entry in enumerate(measurement.accuracyRanges): logging.info(f" [{index}] rangeMin:{range_entry.rangeMin} rangeMax:{range_entry.rangeMax} percentMax:{range_entry.percentMax} percentMin:{range_entry.percentMin} percentTypical:{range_entry.percentTypical} fixedMax:{range_entry.fixedMax} fixedMin:{range_entry.fixedMin} fixedTypical:{range_entry.fixedTypical}") - asserts.assert_greater(range_entry.rangeMax, range_entry.rangeMin, "rangeMax should be > rangeMin") + asserts.assert_greater( + range_entry.rangeMax, range_entry.rangeMin, "rangeMax should be > rangeMin") if index == 0: minimum_range = range_entry.rangeMin maximum_range = range_entry.rangeMax @@ -129,7 +152,8 @@ async def test_TC_EPM_2_1(self): asserts.assert_equal(minimum_range, measurement.minMeasuredValue, "The minMeasuredValue must be the same as any of the minimum of all rangeMin's") - asserts.assert_is(found_active_power, True, "There must be an ActivePower measurement accuracy") + asserts.assert_is(found_active_power, True, + "There must be an ActivePower measurement accuracy") asserts.assert_equal(len(accuracy), number_of_measurements, "The number of accuracy entries should match the NumberOfMeasurementTypes") @@ -202,9 +226,11 @@ async def test_TC_EPM_2_1(self): logger.info(f"Rx'd HarmonicCurrents: {harmonic_currents}") asserts.assert_is(type(harmonic_currents), list) for index, entry in enumerate(harmonic_currents): - logging.info(f" [{index}] order:{entry.order} measurement:{entry.measurement}") + logging.info( + f" [{index}] order:{entry.order} measurement:{entry.measurement}") asserts.assert_greater_equal(entry.order, 1) - self.check_value_in_range("Measurement", entry.measurement, MIN_INT64_ALLOWED, MAX_INT64_ALLOWED) + self.check_value_in_range( + "Measurement", entry.measurement, MIN_INT64_ALLOWED, MAX_INT64_ALLOWED) self.step("18") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.HarmonicPhases.attribute_id in supported_attributes): @@ -212,9 +238,11 @@ async def test_TC_EPM_2_1(self): logger.info(f"Rx'd HarmonicPhases: {harmonic_phases}") asserts.assert_is(type(harmonic_phases), list) for index, entry in enumerate(harmonic_phases): - logging.info(f" [{index}] order:{entry.order} measurement:{entry.measurement}") + logging.info( + f" [{index}] order:{entry.order} measurement:{entry.measurement}") asserts.assert_greater_equal(entry.order, 1) - self.check_value_in_range("Measurement", entry.measurement, MIN_INT64_ALLOWED, MAX_INT64_ALLOWED) + self.check_value_in_range( + "Measurement", entry.measurement, MIN_INT64_ALLOWED, MAX_INT64_ALLOWED) self.step("19") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.PowerFactor.attribute_id in supported_attributes): diff --git a/src/python_testing/TC_EPM_2_2.py b/src/python_testing/TC_EPM_2_2.py index b4a1079ce81b11..629bf0e739d866 100644 --- a/src/python_testing/TC_EPM_2_2.py +++ b/src/python_testing/TC_EPM_2_2.py @@ -44,17 +44,25 @@ def pics_TC_EPM_2_2(self): def steps_TC_EPM_2_2(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EPM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EPM.TEST_EVENT_TRIGGER for Start Fake Load Test 1kW Event"), TestStep("4", "Wait 3 seconds"), - TestStep("4a", "TH reads from the DUT the ActivePower attribute. Verify the read is successful and that the value is between 980'000 and 1'020'000 mW. Note the value read."), - TestStep("4b", "TH reads from the DUT the ActiveCurrent attribute. Verify the read is successful and that the value is between 3'848 and 4'848 mA. Note the value read."), - TestStep("4c", "TH reads from the DUT the Voltage attribute. Verify the read is successful and that the value is between 229'000 and 231'000 mV. Note the value read."), - TestStep("5", "Wait 3 seconds"), - TestStep("5a", "TH reads from the DUT the ActivePower attribute. Verify the read is successful, that the value is between '980'000 and 1'020'000 mW, and the value is different from the value read in step 4a."), - TestStep("5b", "TH reads from the DUT the ActiveCurrent attribute. Verify the read is successful, that the value is between 3'848 and 4'848 mA, and the value is different from the value read in step 4b."), - TestStep("5c", "TH reads from the DUT the Voltage attribute. Verify the read is successful, that the value is between 229'000 and 231'000 mV, and the value is different from the value read in step 4c."), + TestStep("4a", "TH reads from the DUT the ActivePower attribute", + "Verify the read is successful and that the value is between 980'000 and 1'020'000 mW. Note the value read."), + TestStep("4b", "TH reads from the DUT the ActiveCurrent attribute", + "Verify the read is successful and that the value is between 3'848 and 4'848 mA. Note the value read."), + TestStep("4c", "TH reads from the DUT the Voltage attribute", + "Verify the read is successful and that the value is between 229'000 and 231'000 mV. Note the value read."), + TestStep("5", "Wait 5 seconds"), + TestStep("5a", "TH reads from the DUT the ActivePower attribute", + "Verify the read is successful, that the value is between '980'000 and 1'020'000 mW, and the value is different from the value read in step 4a."), + TestStep("5b", "TH reads from the DUT the ActiveCurrent attribute", + "Verify the read is successful, that the value is between 3'848 and 4'848 mA, and the value is different from the value read in step 4b."), + TestStep("5c", "TH reads from the DUT the Voltage attribute", + "Verify the read is successful, that the value is between 229'000 and 231'000 mV, and the value is different from the value read in step 4c."), TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EPM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EPM.TEST_EVENT_TRIGGER for Stop Fake Readings Test Event."), ] @@ -78,36 +86,43 @@ async def test_TC_EPM_2_2(self): self.step("4a") # Active power is Mandatory - active_power = await self.check_epm_attribute_in_range("ActivePower", 980000, 1020000) # 1kW +/- 20W + # 1kW +/- 20W + active_power = await self.check_epm_attribute_in_range("ActivePower", 980000, 1020000) self.step("4b") if self.pics_guard(self.check_pics("EPM.S.A0005")): - active_current = await self.check_epm_attribute_in_range("ActiveCurrent", 3848, 4848) # 4.348 A +/- 500mA + # 4.348 A +/- 500mA + active_current = await self.check_epm_attribute_in_range("ActiveCurrent", 3848, 4848) self.step("4c") if self.pics_guard(self.check_pics("EPM.S.A0004")): - voltage = await self.check_epm_attribute_in_range("Voltage", 229000, 231000) # 230V +/- 1V + # 230V +/- 1V + voltage = await self.check_epm_attribute_in_range("Voltage", 229000, 231000) self.step("5") - # After 3 seconds... - time.sleep(3) + # After 5 seconds... + time.sleep(5) self.step("5a") # Active power is Mandatory - active_power2 = await self.check_epm_attribute_in_range("ActivePower", 980000, 1020000) # 1kW +/- 20W + # 1kW +/- 20W + active_power2 = await self.check_epm_attribute_in_range("ActivePower", 980000, 1020000) asserts.assert_not_equal(active_power, active_power2, f"Expected ActivePower readings to have changed {active_power}, {active_power2}") self.step("5b") if self.pics_guard(self.check_pics("EPM.S.A0005")): - active_current2 = await self.check_epm_attribute_in_range("ActiveCurrent", 3848, 4848) # 4.348 A +/- 500mA + # 4.348 A +/- 500mA + active_current2 = await self.check_epm_attribute_in_range("ActiveCurrent", 3848, 4848) asserts.assert_not_equal(active_current, active_current2, f"Expected ActiveCurrent readings to have changed {active_current}, {active_current2}") self.step("5c") if self.pics_guard(self.check_pics("EPM.S.A0004")): - voltage2 = await self.check_epm_attribute_in_range("Voltage", 229000, 231000) # 230V +/- 1V - asserts.assert_not_equal(voltage, voltage2, f"Expected Voltage readings to have changed {voltage}, {voltage2}") + # 230V +/- 1V + voltage2 = await self.check_epm_attribute_in_range("Voltage", 229000, 231000) + asserts.assert_not_equal( + voltage, voltage2, f"Expected Voltage readings to have changed {voltage}, {voltage2}") self.step("6") await self.send_test_event_trigger_stop_fake_readings() diff --git a/src/python_testing/TC_IDM_4_2.py b/src/python_testing/TC_IDM_4_2.py index 60016ba4dcf20a..b159bb76a1e31c 100644 --- a/src/python_testing/TC_IDM_4_2.py +++ b/src/python_testing/TC_IDM_4_2.py @@ -15,16 +15,24 @@ # limitations under the License. # +# test-runner-runs: run1 +# test-runner-run/run1/app: ${ALL_CLUSTERS_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto + import copy import logging import time import chip.clusters as Clusters from chip.ChipDeviceCtrl import ChipDeviceController +from chip.clusters import ClusterObjects as ClusterObjects from chip.clusters.Attribute import AttributePath, TypedAttributePath from chip.exceptions import ChipStackError from chip.interaction_model import Status -from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from matter_testing_support import AttributeChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts ''' @@ -45,11 +53,37 @@ class TC_IDM_4_2(MatterBaseTest): - ROOT_NODE_ENDPOINT_ID = 0 + def steps_TC_IDM_4_2(self): + return [TestStep(0, "CR1 reads the ServerList attribute from the Descriptor cluster on EP0.", + "If the ICD Management cluster ID (70,0x46) is present, set SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC = IdleModeDuration and min_interval_floor_s to 0, otherwise, set SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC = 60 mins and min_interval_floor_s to 3."), + TestStep(1, "CR1 sends a subscription message to the DUT with MaxIntervalCeiling set to a value greater than subscription_max_interval_publisher_limit_sec. DUT sends a report data action to the TH. CR1 sends a success status response to the DUT. DUT sends a Subscribe Response Message to the CR1 to activate the subscription.", + "Verify on the CR1, a report data message is received. Verify it contains the following data Report data - data of the attribute/event requested earlier. Verify on the CR1 the Subscribe Response has the following fields, SubscriptionId - Verify it is of type uint32. MaxInterval - Verify it is of type uint32. Verify that the MaxInterval is less than or equal to MaxIntervalCeiling."), + TestStep(2, "CR1 sends a subscription message to the DUT with MaxIntervalCeiling set to a value less than subscription_max_interval_publisher_limit_sec. DUT sends a report data action to the CR1. CR1 sends a success status response to the DUT. DUT sends a Subscribe Response Message to the CR1 to activate the subscription.", + "Verify on the CR1, a report data message is received. Verify it contains the following data: Report data - data of the attribute/event requested earlier. Verify on the CR1 the Subscribe Response has the following fields, SubscriptionId - Verify it is of type uint32. MaxInterval - Verify it is of type uint32. Verify that the MaxInterval is less than or equal to SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT."), + TestStep(3, "Setup CR2 such that it does not have access to a specific cluster. CR2 sends a subscription message to subscribe to an attribute on that cluster for which it does not have access.", + "Verify that the DUT returns a \"INVALID_ACTION\" status response."), + TestStep(4, "Setup CR2 such that it does not have access to all attributes on a specific cluster and endpoint. CR2 sends a subscription request to subscribe to all attributes for which it does not have access.", + "Verify that the DUT returns a \"INVALID_ACTION\" status response."), + TestStep(5, "Setup CR2 such that it does not have access to an Endpoint. CR2 sends a subscription request to subscribe to all attributes on all clusters on a specific Endpoint for which it does not have access.", + "Verify that the DUT returns a \"INVALID_ACTION\" status response."), + TestStep(6, "Setup CR2 such that it does not have access to the Node. CR2 sends a subscription request to subscribe to all attributes on all clusters on all endpoints on a Node for which it does not have access.", + "Verify that the DUT returns a \"INVALID_ACTION\" status response."), + TestStep(7, "CR1 sends a subscription request action for an attribute with an empty DataVersionFilters field. DUT sends a report data action with the data of the attribute along with the data version. Tear down the subscription for that attribute. Start another subscription with the DataVersionFilter field set to the data version received above.", + "Verify that the subscription is activated between CR1 and DUT."), + TestStep(8, "CR1 sends a subscription request action for an attribute and sets the MinIntervalFloor to min_interval_floor_sec and MaxIntervalCeiling to 10. Activate the Subscription between CR1 and DUT and record the time when the priming ReportDataMessage is received as t_report_sec. Save the returned MaxInterval from the SubscribeResponseMessage as max_interval_sec."), + TestStep(9, "CR1 modifies the attribute which has been subscribed to on the DUT and waits for an incoming ReportDataMessage", + "Verify that t_update - t_report is greater than min_interval_floor_s and less than the ReadClient SubscriptionTimeout (calculated by the ReadClient using max_interval_s and the maximum estimated network delay based on the MRP parameters for retries with backoff)"), + TestStep(10, "CR1 sends a subscription request action for an attribute and set the MinIntervalFloor value to be greater than MaxIntervalCeiling.", + "Verify that the DUT sends an error message and the subscription is not established."), + TestStep(11, "CR1 sends a subscription request to subscribe to a specific global attribute from all clusters on all endpoints.", + "Verify that the Subscription succeeds and the DUT sends back the attribute values for the global attribute."), + TestStep(12, "CR1 sends a subscription request to subscribe to a global attribute on an endpoint on all clusters.", + "Verify that the Subscription succeeds and the DUT sends back the attribute values for the global attribute. Verify no data from other endpoints is sent back."), + TestStep(13, "CR1 sends a subscription request to the DUT with both AttributeRequests and EventRequests as empty.", + "Verify that the Subscription does not succeed and the DUT sends back a Status Response Action with the INVALID_ACTION Status Code") + ] - async def write_acl(self, ctrl, acl, ep=ROOT_NODE_ENDPOINT_ID): - result = await ctrl.WriteAttribute(self.dut_node_id, [(ep, Clusters.AccessControl.Attributes.Acl(acl))]) - asserts.assert_equal(result[ep].Status, Status.Success, "ACL write failed") + ROOT_NODE_ENDPOINT_ID = 0 async def get_descriptor_server_list(self, ctrl, ep=ROOT_NODE_ENDPOINT_ID): return await self.read_single_attribute_check_success( @@ -59,6 +93,14 @@ async def get_descriptor_server_list(self, ctrl, ep=ROOT_NODE_ENDPOINT_ID): attribute=Clusters.Descriptor.Attributes.ServerList ) + async def get_descriptor_parts_list(self, ctrl, ep=ROOT_NODE_ENDPOINT_ID): + return await self.read_single_attribute_check_success( + endpoint=ep, + dev_ctrl=ctrl, + cluster=Clusters.Descriptor, + attribute=Clusters.Descriptor.Attributes.PartsList + ) + async def get_idle_mode_duration_sec(self, ctrl, ep=ROOT_NODE_ENDPOINT_ID): return await self.read_single_attribute_check_success( endpoint=ep, @@ -81,14 +123,18 @@ def verify_attribute_exists(sub, cluster, attribute, ep=ROOT_NODE_ENDPOINT_ID): @staticmethod def get_typed_attribute_path(attribute, ep=ROOT_NODE_ENDPOINT_ID): return TypedAttributePath( - Path=AttributePath( + Path=AttributePath.from_attribute( EndpointId=ep, Attribute=attribute ) ) - async def get_dut_acl(self, ep=ROOT_NODE_ENDPOINT_ID): - sub = await self.default_controller.ReadAttribute( + async def write_dut_acl(self, ctrl, acl, ep=ROOT_NODE_ENDPOINT_ID): + result = await ctrl.WriteAttribute(self.dut_node_id, [(ep, Clusters.AccessControl.Attributes.Acl(acl))]) + asserts.assert_equal(result[ep].Status, Status.Success, "ACL write failed") + + async def get_dut_acl(self, ctrl, ep=ROOT_NODE_ENDPOINT_ID): + sub = await ctrl.ReadAttribute( nodeid=self.dut_node_id, attributes=[(ep, Clusters.AccessControl.Attributes.Acl)], keepSubscriptions=False, @@ -99,11 +145,10 @@ async def get_dut_acl(self, ep=ROOT_NODE_ENDPOINT_ID): return acl_list - async def add_ace_to_dut_acl(self, ctrl, ace): - dut_acl_original = await self.get_dut_acl() + async def add_ace_to_dut_acl(self, ctrl, ace, dut_acl_original): dut_acl = copy.deepcopy(dut_acl_original) dut_acl.append(ace) - await self.write_acl(ctrl=ctrl, acl=dut_acl) + await self.write_dut_acl(ctrl=ctrl, acl=dut_acl) @staticmethod def is_valid_uint32_value(var): @@ -121,8 +166,7 @@ async def test_TC_IDM_4_2(self): cluster_rev_attr_typed_path = self.get_typed_attribute_path(cluster_rev_attr) node_label_attr = Clusters.BasicInformation.Attributes.NodeLabel node_label_attr_path = [(0, node_label_attr)] - node_label_attr_typed_path = self.get_typed_attribute_path(node_label_attr) - SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC = 0 + subscription_max_interval_publisher_limit_sec = 0 INVALID_ACTION_ERROR_CODE = 0x580 # Controller 1 setup @@ -130,6 +174,9 @@ async def test_TC_IDM_4_2(self): # Will write ACL for controller 2 and validate success/error codes CR1: ChipDeviceController = self.default_controller + # Original DUT ACL used for reseting the ACL on some steps + dut_acl_original = await self.get_dut_acl(CR1) + # Controller 2 setup # Subscriber/client with limited access to the DUT # Will validate error status codes @@ -140,8 +187,14 @@ async def test_TC_IDM_4_2(self): paaTrustStorePath=str(self.matter_test_config.paa_trust_store_path), ) - # Read ServerList attribute - self.print_step("0a", "CR1 reads the Descriptor cluster ServerList attribute from EP0") + # *** Step 0 *** + # CR1 reads the ServerList attribute from the Descriptor cluster on EP0. If the ICDManagement cluster ID + # (70,0x46) is present, set SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC = IdleModeDuration and + # min_interval_floor_s to 0, otherwise, set SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC = 60 mins and + # min_interval_floor_s to 3. + self.step(0) + + # Reads the ServerList attribute ep0_servers = await self.get_descriptor_server_list(CR1) # Check if ep0_servers contains the ICD Management cluster ID (0x0046) @@ -151,19 +204,27 @@ async def test_TC_IDM_4_2(self): "CR1 reads from the DUT the IdleModeDuration attribute and sets SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC = IdleModeDuration") idleModeDuration = await self.get_idle_mode_duration_sec(CR1) - - SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC = idleModeDuration + subscription_max_interval_publisher_limit_sec = idleModeDuration + min_interval_floor_sec = 0 else: # Defaulting SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC to 60 minutes - SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC = 60 * 60 + subscription_max_interval_publisher_limit_sec = 60 * 60 + min_interval_floor_sec = 3 + + asserts.assert_greater_equal(subscription_max_interval_publisher_limit_sec, 1, + "SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC must be at least 1") logging.info( - f"Set SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC to {SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC} seconds") + f"Set SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC to {subscription_max_interval_publisher_limit_sec} seconds") # *** Step 1 *** - self.print_step(1, "CR1 sends a subscription message to the DUT with MaxIntervalCeiling set to a value greater than SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC. DUT sends a report data action to the TH. CR1 sends a success status response to the DUT. DUT sends a Subscribe Response Message to the CR1 to activate the subscription.") - min_interval_floor_sec = 1 - max_interval_ceiling_sec = SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC + 5 + # CR1 sends a subscription message to the DUT with MaxIntervalCeiling set to a value greater than + # SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC. DUT sends a report data action to the TH. CR1 sends + # a success status response to the DUT. DUT sends a Subscribe Response Message to the CR1 to activate + # the subscription. + self.step(1) + + max_interval_ceiling_sec = subscription_max_interval_publisher_limit_sec + 5 asserts.assert_greater(max_interval_ceiling_sec, min_interval_floor_sec, "MaxIntervalCeiling must be greater than MinIntervalFloor") @@ -198,9 +259,15 @@ async def test_TC_IDM_4_2(self): sub_cr1_step1.Shutdown() # *** Step 2 *** - self.print_step(2, "CR1 sends a subscription message to the DUT with MaxIntervalCeiling set to a value less than SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC. DUT sends a report data action to the CR1. CR1 sends a success status response to the DUT. DUT sends a Subscribe Response Message to the CR1 to activate the subscription.") - min_interval_floor_sec = 1 - max_interval_ceiling_sec = max(2, SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC - 5) + # CR1 sends a subscription message to the DUT with MaxIntervalCeiling set to a value less than + # subscription_max_interval_publisher_limit_sec. DUT sends a report data action to the CR1. + # CR1 sends a success status response to the DUT. DUT sends a Subscribe Response Message to the + # CR1 to activate the subscription. + self.step(2) + + min_interval_floor_sec = 0 + + max_interval_ceiling_sec = max(1, subscription_max_interval_publisher_limit_sec - 5) asserts.assert_greater(max_interval_ceiling_sec, min_interval_floor_sec, "MaxIntervalCeiling must be greater than MinIntervalFloor") @@ -229,13 +296,18 @@ async def test_TC_IDM_4_2(self): "MaxInterval is not of uint32 type.") # Verify MaxInterval is less than or equal to MaxIntervalCeiling - asserts.assert_less_equal(sub_cr1_step2_max_interval_ceiling_sec, SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC, + asserts.assert_less_equal(sub_cr1_step2_max_interval_ceiling_sec, subscription_max_interval_publisher_limit_sec, "MaxInterval is not less than or equal to SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT_SEC") sub_cr1_step2.Shutdown() # *** Step 3 *** - self.print_step(3, "Setup CR2 such that it does not have access to a specific cluster. CR2 sends a subscription message to subscribe to an attribute on that cluster for which it does not have access.") + # Setup CR2 such that it does not have access to a specific cluster. CR2 sends a subscription + # message to subscribe to an attribute on that cluster for which it does not have access. + self.step(3) + + # Setting max_interval_ceiling_sec value for steps 3-8 + max_interval_ceiling_sec = 10 # Limited ACE for controller 2 with single cluster access CR2_limited_ace = Clusters.AccessControl.Structs.AccessControlEntryStruct( @@ -244,18 +316,20 @@ async def test_TC_IDM_4_2(self): targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(cluster=Clusters.BasicInformation.id)], subjects=[CR2_nodeid]) - self.add_ace_to_dut_acl(CR1, CR2_limited_ace) + # Add limited ACE + await self.add_ace_to_dut_acl(CR1, CR2_limited_ace, dut_acl_original) # Controller 2 tries to subscribe an attribute from a cluster # it doesn't have access to # "INVALID_ACTION" status response expected + try: await CR2.ReadAttribute( nodeid=self.dut_node_id, # Attribute from a cluster controller 2 has no access to attributes=[(0, Clusters.AccessControl.Attributes.Acl)], keepSubscriptions=False, - reportInterval=[3, 3], + reportInterval=(min_interval_floor_sec, max_interval_ceiling_sec), autoResubscribe=False ) asserts.fail("Expected exception not thrown") @@ -265,7 +339,10 @@ async def test_TC_IDM_4_2(self): "Incorrect error response for subscription to unallowed cluster") # *** Step 4 *** - self.print_step(4, "Setup CR2 such that it does not have access to all attributes on a specific cluster and endpoint. CR2 sends a subscription request to subscribe to all attributes for which it does not have access.") + # Setup CR2 such that it does not have access to all attributes on a specific cluster and + # endpoint. CR2 sends a subscription request to subscribe to all attributes for which it + # does not have access. + self.step(4) # Limited ACE for controller 2 with single cluster access and specific endpoint CR2_limited_ace = Clusters.AccessControl.Structs.AccessControlEntryStruct( @@ -273,10 +350,11 @@ async def test_TC_IDM_4_2(self): authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct( endpoint=1, - cluster=Clusters.BasicInformation.id)], + cluster=Clusters.Descriptor.id)], subjects=[CR2_nodeid]) - self.add_ace_to_dut_acl(CR1, CR2_limited_ace) + # Add limited ACE + await self.add_ace_to_dut_acl(CR1, CR2_limited_ace, dut_acl_original) # Controller 2 tries to subscribe to all attributes from a cluster # it doesn't have access to @@ -287,7 +365,7 @@ async def test_TC_IDM_4_2(self): # Cluster controller 2 has no access to attributes=[(0, Clusters.BasicInformation)], keepSubscriptions=False, - reportInterval=[3, 3], + reportInterval=(min_interval_floor_sec, max_interval_ceiling_sec), autoResubscribe=False ) raise ValueError("Expected exception not thrown") @@ -296,17 +374,30 @@ async def test_TC_IDM_4_2(self): asserts.assert_equal(e.err, INVALID_ACTION_ERROR_CODE, "Incorrect error response for subscription to unallowed cluster") + await self.write_dut_acl(CR1, dut_acl_original) + acl_list = await self.get_dut_acl(CR1) + print(f'acl_list - reset 4: {acl_list}') + # *** Step 5 *** - self.print_step(5, "Setup CR2 such that it does not have access to an Endpoint. CR2 sends a subscription request to subscribe to all attributes on all clusters on a specific Endpoint for which it does not have access.") + # Setup CR2 such that it does not have access to an Endpoint. CR2 sends a subscription + # request to subscribe to all attributes on all clusters on a specific Endpoint for which + # it does not have access. + self.step(5) + + # Get first value of parts list for the endpoint + parts_list = await self.get_descriptor_parts_list(CR1) + asserts.assert_greater(len(parts_list), 0, "Parts list is empty.") + endpoint = parts_list[0] # Limited ACE for controller 2 with endpoint 1 access only to all clusters and all attributes CR2_limited_ace = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kView, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=1)], + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint)], subjects=[CR2_nodeid]) - self.add_ace_to_dut_acl(CR1, CR2_limited_ace) + # Add limited ACE + await self.add_ace_to_dut_acl(CR1, CR2_limited_ace, dut_acl_original) # Controller 2 tries to subscribe to all attributes from all clusters # on an endpoint it doesn't have access to @@ -317,7 +408,7 @@ async def test_TC_IDM_4_2(self): # Endpoint controller 2 has no access to attributes=[(0)], keepSubscriptions=False, - reportInterval=[3, 3], + reportInterval=(min_interval_floor_sec, max_interval_ceiling_sec), autoResubscribe=False ) raise ValueError("Expected exception not thrown") @@ -327,14 +418,15 @@ async def test_TC_IDM_4_2(self): "Incorrect error response for subscription to unallowed endpoint") # *** Step 6 *** - self.print_step(6, "Setup CR2 such that it does not have access to the Node. CR2 sends a subscription request to subscribe to all attributes on all clusters on all endpoints on a Node for which it does not have access.") + # Setup CR2 such that it does not have access to the Node. CR2 sends a subscription + # request to subscribe to all attributes on all clusters on all endpoints on a Node + # for which it does not have access. + self.step(6) - # Skip setting an ACE for controller 2 so - # the DUT node rejects subscribing to it + # Skip setting an ACE for controller 2 so the DUT node rejects subscribing to it - # Write original DUT ACL into DUT - dut_acl_original = await self.get_dut_acl() - await self.write_acl(ctrl=CR1, acl=dut_acl_original) + # Restore original DUT ACL + await self.write_dut_acl(CR1, dut_acl_original) # Controller 2 tries to subscribe to all attributes from all clusters # from all endpoints on a node it doesn't have access to @@ -345,7 +437,7 @@ async def test_TC_IDM_4_2(self): nodeid=self.dut_node_id, attributes=[], keepSubscriptions=False, - reportInterval=[3, 3], + reportInterval=(min_interval_floor_sec, max_interval_ceiling_sec), autoResubscribe=False ) raise ValueError("Expected exception not thrown") @@ -355,7 +447,12 @@ async def test_TC_IDM_4_2(self): "Incorrect error response for subscription to unallowed node") # *** Step 7 *** - self.print_step(7, "CR1 sends a subscription request action for an attribute with an empty DataVersionFilters field. DUT sends a report data action with the data of the attribute along with the data version. Tear down the subscription for that attribute. Start another subscription with the DataVersionFilter field set to the data version received above.") + # CR1 sends a subscription request action for an attribute with an empty + # DataVersionFilters field. DUT sends a report data action with the data + # of the attribute along with the data version. Tear down the subscription + # for that attribute. Start another subscription with the DataVersionFilter + # field set to the data version received above. + self.step(7) # Subscribe to attribute with empty dataVersionFilters sub_cr1_empty_dvf = await CR1.ReadAttribute( @@ -376,94 +473,126 @@ async def test_TC_IDM_4_2(self): data_version_filter = [(0, Clusters.BasicInformation, data_version)] # Subscribe to attribute with provided DataVersion - sub_cr1_provided_dvf = await CR1.ReadAttribute( + sub_cr1_step7 = await CR1.ReadAttribute( nodeid=self.dut_node_id, attributes=node_label_attr_path, - reportInterval=(10, 20), + reportInterval=(min_interval_floor_sec, max_interval_ceiling_sec), keepSubscriptions=False, dataVersionFilters=data_version_filter ) # Verify that the subscription is activated between CR1 and DUT - asserts.assert_true(sub_cr1_provided_dvf.subscriptionId, "Subscription not activated") + asserts.assert_true(sub_cr1_step7.subscriptionId, "Subscription not activated") - sub_cr1_provided_dvf.Shutdown() + sub_cr1_step7.Shutdown() # *** Step 8 *** - self.print_step(8, "CR1 sends a subscription request action for an attribute and sets the MinIntervalFloor value to be same as MaxIntervalCeiling. Activate the Subscription between CR1 and DUT. Modify the attribute which has been subscribed to on the DUT.") + # CR1 sends a subscription request action for an attribute and sets the + # MinIntervalFloor to min_interval_floor_sec and MaxIntervalCeiling to 10. + # Activate the Subscription between CR1 and DUT and record the time when + # the priming ReportDataMessage is received as t_report_sec. Save the + # returned MaxInterval from the SubscribeResponseMessage as max_interval_sec. + self.step(8) # Subscribe to attribute - same_min_max_interval_sec = 3 sub_cr1_update_value = await CR1.ReadAttribute( nodeid=self.dut_node_id, attributes=node_label_attr_path, - reportInterval=(same_min_max_interval_sec, same_min_max_interval_sec), + reportInterval=(min_interval_floor_sec, max_interval_ceiling_sec), keepSubscriptions=False ) - # Modify attribute value + # Record the time when the priming ReportDataMessage is received + t_report_sec = time.time() + + # *** Step 9 *** + # CR1 modifies the attribute which has been subscribed to on the DUT + # and waits for an incoming ReportDataMessage + self.step(9) + + # Saving the returned MaxInterval from the SubscribeResponseMessage + min_interval_floor_sec, max_interval_sec = sub_cr1_update_value.GetReportingIntervalsSeconds() + + # Get subscription timeout + subscription_timeout_sec = sub_cr1_update_value.GetSubscriptionTimeoutMs() / 1000 + + # Set Attribute Update Callback + node_label_update_cb = AttributeChangeCallback(node_label_attr) + sub_cr1_update_value.SetAttributeUpdateCallback(node_label_update_cb) + + # Update attribute value new_node_label_write = "NewNodeLabel_011235813" await CR1.WriteAttribute( self.dut_node_id, [(0, node_label_attr(value=new_node_label_write))] ) - # Wait MinIntervalFloor seconds before reading updated attribute value - time.sleep(same_min_max_interval_sec) - new_node_label_read = sub_cr1_update_value.GetAttribute(node_label_attr_typed_path) + node_label_update_cb.wait_for_report() + + # Save the time that the report is received + t_update_sec = time.time() + + # Elapsed time between attribute subscription and write update + t_elapsed_sec = t_update_sec - t_report_sec - # Verify new attribute value after MinIntervalFloor time - asserts.assert_equal(new_node_label_read, new_node_label_write, "Attribute value not updated after write operation.") + # Verify that t_update - t_report is greater than min_interval_floor_s and less than the ReadClient SubscriptionTimeout + asserts.assert_greater(t_elapsed_sec, min_interval_floor_sec, + f"t_update_sec - t_report_sec ({t_elapsed_sec}s) must be greater than min_interval_floor_sec ({min_interval_floor_sec}s)") + asserts.assert_less(t_elapsed_sec, subscription_timeout_sec, + f"t_update_sec - t_report_sec ({t_elapsed_sec}s) must be less than subscription_timeout_sec ({subscription_timeout_sec}s)") sub_cr1_update_value.Shutdown() - # *** Step 9 *** - self.print_step( - 9, "CR1 sends a subscription request action for an attribute and set the MinIntervalFloor value to be greater than MaxIntervalCeiling.") + # *** Step 10 *** + # CR1 sends a subscription request action for an attribute and set the MinIntervalFloor + # value to be greater than MaxIntervalCeiling. + self.step(10) - # Subscribe to attribute with invalid reportInterval arguments, expect and exception + # Subscribe to attribute with invalid reportInterval arguments, expect an error sub_cr1_invalid_intervals = None - try: + with asserts.assert_raises(ChipStackError, "Expected exception wasn't thrown."): sub_cr1_invalid_intervals = await CR1.ReadAttribute( nodeid=self.dut_node_id, attributes=node_label_attr_path, reportInterval=(20, 10), keepSubscriptions=False ) - except ChipStackError: - # Verify no subscription is established - with asserts.assert_raises(AttributeError): - sub_cr1_invalid_intervals.subscriptionId - except Exception: - asserts.fail("Expected exception was not thrown") - # *** Step 10 *** - self.print_step( - 10, "CR1 sends a subscription request to subscribe to a specific global attribute from all clusters on all endpoints.") + # Verify no subscription was established + with asserts.assert_raises(AttributeError): + sub_cr1_invalid_intervals.subscriptionId + + # *** Step 11 *** + # CR1 sends a subscription request to subscribe to a specific global attribute from + # all clusters on all endpoints. + self.step(11) + + # Setting max_interval_ceiling_sec value for steps 11-13 + max_interval_ceiling_sec = 10 # Omitting endpoint to indicate endpoint wildcard cluster_rev_attr_path = [(cluster_rev_attr)] # Subscribe to global attribute - sub_cr1_step10 = await CR1.ReadAttribute( + sub_cr1_step11 = await CR1.ReadAttribute( nodeid=self.dut_node_id, attributes=cluster_rev_attr_path, - reportInterval=(3, 3), + reportInterval=(min_interval_floor_sec, max_interval_ceiling_sec), keepSubscriptions=False ) # Verify that the subscription is activated between CR1 and DUT - asserts.assert_true(sub_cr1_step10.subscriptionId, "Subscription not activated") + asserts.assert_true(sub_cr1_step11.subscriptionId, "Subscription not activated") # Verify attribute came back self.verify_attribute_exists( - sub=sub_cr1_step10, + sub=sub_cr1_step11, cluster=Clusters.BasicInformation, attribute=cluster_rev_attr ) # Verify DUT sends back the attribute values for the global attribute - cluster_revision_attr_value = sub_cr1_step10.GetAttribute(cluster_rev_attr_typed_path) + cluster_revision_attr_value = sub_cr1_step11.GetAttribute(cluster_rev_attr_typed_path) # Verify ClusterRevision is of uint16 type asserts.assert_true(self.is_valid_uint16_value(cluster_revision_attr_value), "ClusterRevision is not of uint16 type.") @@ -471,58 +600,60 @@ async def test_TC_IDM_4_2(self): # Verify valid ClusterRevision value asserts.assert_greater_equal(cluster_revision_attr_value, 0, "Invalid ClusterRevision value.") - sub_cr1_step10.Shutdown() + sub_cr1_step11.Shutdown() - # *** Step 11 *** - self.print_step(11, "CR1 sends a subscription request to subscribe to a global attribute on an endpoint on all clusters.") + # *** Step 12 *** + # CR1 sends a subscription request to subscribe to a global attribute on an endpoint on all clusters. + self.step(12) # Specifying single endpoint 0 requested_ep = 0 cluster_rev_attr_path = [(requested_ep, cluster_rev_attr)] # Subscribe to global attribute - sub_cr1_step11 = await CR1.ReadAttribute( + sub_cr1_step12 = await CR1.ReadAttribute( nodeid=self.dut_node_id, attributes=cluster_rev_attr_path, - reportInterval=(3, 3), + reportInterval=(min_interval_floor_sec, max_interval_ceiling_sec), keepSubscriptions=False ) # Verify that the subscription is activated between CR1 and DUT - asserts.assert_true(sub_cr1_step11.subscriptionId, "Subscription not activated") + asserts.assert_true(sub_cr1_step12.subscriptionId, "Subscription not activated") # Verify attribute came back self.verify_attribute_exists( - sub=sub_cr1_step11, + sub=sub_cr1_step12, cluster=Clusters.BasicInformation, attribute=cluster_rev_attr ) # Verify no data from other endpoints is sent back - attributes = sub_cr1_step11.GetAttributes() + attributes = sub_cr1_step12.GetAttributes() ep_keys = list(attributes.keys()) asserts.assert_true(len(ep_keys) == 1, "More than one endpoint returned, exactly 1 was expected") # Verify DUT sends back the attribute values for the global attribute cluster_rev_attr_typed_path = self.get_typed_attribute_path(cluster_rev_attr) - cluster_revision_attr_value = sub_cr1_step11.GetAttribute(cluster_rev_attr_typed_path) + cluster_revision_attr_value = sub_cr1_step12.GetAttribute(cluster_rev_attr_typed_path) # Verify ClusterRevision is of uint16 type asserts.assert_true(self.is_valid_uint16_value(cluster_revision_attr_value), "ClusterRevision is not of uint16 type.") - sub_cr1_step11.Shutdown() + sub_cr1_step12.Shutdown() - # *** Step 12 *** - self.print_step(12, "CR1 sends a subscription request to the DUT with both AttributeRequests and EventRequests as empty.") + # *** Step 13 *** + # CR1 sends a subscription request to the DUT with both AttributeRequests and EventRequests as empty. + self.step(13) # Attempt a subscription with both AttributeRequests and EventRequests as empty - sub_cr1_step12 = None + sub_cr1_step13 = None try: - sub_cr1_step12 = await CR1.Read( + sub_cr1_step13 = await CR1.Read( nodeid=self.dut_node_id, attributes=[], events=[], - reportInterval=(3, 3) + reportInterval=(min_interval_floor_sec, max_interval_ceiling_sec), ) raise ValueError("Expected exception not thrown") except ChipStackError as e: @@ -532,7 +663,7 @@ async def test_TC_IDM_4_2(self): # Verify no subscription is established with asserts.assert_raises(AttributeError): - sub_cr1_step12.subscriptionId + sub_cr1_step13.subscriptionId except Exception: asserts.fail("Expected exception was not thrown") diff --git a/src/python_testing/TC_pics_checker.py b/src/python_testing/TC_pics_checker.py index 4e503edd101a01..f63628fd4eb426 100644 --- a/src/python_testing/TC_pics_checker.py +++ b/src/python_testing/TC_pics_checker.py @@ -20,7 +20,7 @@ from basic_composition_support import BasicCompositionTests from global_attribute_ids import GlobalAttributeIds from matter_testing_support import (AttributePathLocation, ClusterPathLocation, CommandPathLocation, FeaturePathLocation, - MatterBaseTest, TestStep, async_test_body, default_matter_test_main) + MatterBaseTest, ProblemLocation, TestStep, async_test_body, default_matter_test_main) from mobly import asserts from pics_support import accepted_cmd_pics_str, attribute_pics_str, feature_pics_str, generated_cmd_pics_str from spec_parsing_support import build_xml_clusters @@ -88,11 +88,12 @@ def _add_pics_for_lists(self, cluster_id: int, attribute_id_of_element_list: Glo def steps_TC_IDM_10_4(self): return [TestStep(1, "TH performs a wildcard read of all attributes on the endpoint under test"), - TestStep(2, "For every standard cluster: If the cluster is present on the endpoint, ensure the server-side PICS code for the cluster is present in the PICS file (e.g. OO.S for On/Off cluster).If the cluster is not present on the endpoint, ensure the cluster server PICS code is not present in the PICS file."), - TestStep(3, "For every standard cluster, for every attribute in the cluster:If the cluster is present on the endpoint and the attribute ID is present in the AttributeList global attribute within the cluster, ensure the server-side PICS code for the attribute is present in the PICS file (e.g. OO.S.A000 for On/Off cluster’s OnOff attribute).Otherwise, ensure the attribute PICS code is NOT present in the PICS file."), - TestStep(4, "For every cluster present in the spec, for every client → server command in the cluster: If the cluster is present on the endpoint and the command id is present in the accepted commands list, ensure the PICS code for the accepted command is present in the PICS file. Otherwise, ensure the accepted command PICS code is not present in the PICS file."), - TestStep(5, "For every cluster present in the spec, for every server → client command in the cluster: If the cluster is present on the endpoint and the command id is present in the generated commands list, ensure the PICS code for the generated command is present in the PICS file. Otherwise, ensure the generated command PICS code is not present in the PICS file."), - TestStep(6, "For every cluster present in the spec, for every feature in the cluster: If the cluster is present on the endpoint and the feature is marked in the feature map, ensure the PICS code for the feature is present in the PICS file. Otherwise, ensure the feature PICS code is not present in the PICS file.")] + TestStep(2, "For every standard cluster: If the cluster is present on the endpoint, ensure the server-side PICS code for the cluster is present in the PICS file (e.g. OO.S for On/Off cluster).If the cluster is not present on the endpoint, ensure the cluster server PICS code is not present in the PICS file.", "PICS exactly match for server clusters."), + TestStep(3, "For every standard cluster, for every attribute in the cluster:If the cluster is present on the endpoint and the attribute ID is present in the AttributeList global attribute within the cluster, ensure the server-side PICS code for the attribute is present in the PICS file (e.g. OO.S.A000 for On/Off cluster’s OnOff attribute).Otherwise, ensure the attribute PICS code is NOT present in the PICS file.", "PICS exactly match for all attributes in all clusters."), + TestStep(4, "For every cluster present in the spec, for every client → server command in the cluster: If the cluster is present on the endpoint and the command id is present in the accepted commands list, ensure the PICS code for the accepted command is present in the PICS file. Otherwise, ensure the accepted command PICS code is not present in the PICS file.", "PICS exactly match for all accepted commands in all clusters."), + TestStep(5, "For every cluster present in the spec, for every server → client command in the cluster: If the cluster is present on the endpoint and the command id is present in the generated commands list, ensure the PICS code for the generated command is present in the PICS file. Otherwise, ensure the generated command PICS code is not present in the PICS file.", "PICS exactly match for all generated commands in all clusters."), + TestStep(6, "For every cluster present in the spec, for every feature in the cluster: If the cluster is present on the endpoint and the feature is marked in the feature map, ensure the PICS code for the feature is present in the PICS file. Otherwise, ensure the feature PICS code is not present in the PICS file.", "PICS exactly match for all features in all clusters."), + TestStep(7, "Ensure that the PICS_SDK_CI_ONLY PICS does not appear in the PICS file", "CI PICS is not present")] def test_TC_IDM_10_4(self): # wildcard read is done in setup_class @@ -175,6 +176,12 @@ def test_TC_IDM_10_4(self): location = ClusterPathLocation(endpoint_id=self.endpoint_id, cluster_id=cluster_id) self._check_and_record_errors(location, required, pics) + self.step(7) + if self.check_pics('PICS_SDK_CI_ONLY'): + self.record_error("PICS check", location=ProblemLocation(), + problem="PICS PICS_SDK_CI_ONLY found in PICS list. This PICS is disallowed for certification.") + self.success = False + if not self.success: self.fail_current_test("At least one PICS error was found for this endpoint") diff --git a/src/python_testing/TestMatterTestingSupport.py b/src/python_testing/TestMatterTestingSupport.py index eba9dc458383e5..d2a259f154adc6 100644 --- a/src/python_testing/TestMatterTestingSupport.py +++ b/src/python_testing/TestMatterTestingSupport.py @@ -625,7 +625,7 @@ def test_xml_pics(self): self.pics_assert('BINFO.S.A0010', True) self.pics_assert('BINFO.S.A0011', False) self.pics_assert('BINFO.S.A0012', True) - self.pics_assert('BINFO.S.A0013', True) + self.pics_assert('BINFO.S.A0013', False) self.pics_assert('BINFO.S.A0014', False) self.pics_assert('PICSDOESNOTEXIST', False) diff --git a/src/python_testing/matter_testing_support.py b/src/python_testing/matter_testing_support.py index 796397c57e0458..b8854e23a7d2ee 100644 --- a/src/python_testing/matter_testing_support.py +++ b/src/python_testing/matter_testing_support.py @@ -34,7 +34,7 @@ from dataclasses import dataclass, field from datetime import datetime, timedelta, timezone from enum import Enum -from typing import List, Optional, Tuple, Union +from typing import List, Optional, Tuple from chip.tlv import float32, uint @@ -52,7 +52,7 @@ from chip import discovery from chip.ChipStack import ChipStack from chip.clusters import ClusterObjects as ClusterObjects -from chip.clusters.Attribute import EventReadResult, SubscriptionTransaction +from chip.clusters.Attribute import EventReadResult, SubscriptionTransaction, TypedAttributePath from chip.exceptions import ChipStackError from chip.interaction_model import InteractionModelError, Status from chip.setup_payload import SetupPayload @@ -266,6 +266,39 @@ def wait_for_event_report(self, expected_event: ClusterObjects.ClusterEvent, tim return res.Data +class AttributeChangeCallback: + def __init__(self, expected_attribute: ClusterObjects.ClusterAttributeDescriptor): + self._output = queue.Queue() + self._expected_attribute = expected_attribute + + def __call__(self, path: TypedAttributePath, transaction: SubscriptionTransaction): + """This is the subscription callback when an attribute is updated. + It checks the passed in attribute is the same as the subscribed to attribute and + then posts it into the queue for later processing.""" + + asserts.assert_equal(path.AttributeType, self._expected_attribute, + f"[AttributeChangeCallback] Attribute mismatch. Expected: {self._expected_attribute}, received: {path.AttributeType}") + logging.debug(f"[AttributeChangeCallback] Attribute update callback for {path.AttributeType}") + q = (path, transaction) + self._output.put(q) + + def wait_for_report(self): + try: + path, transaction = self._output.get(block=True, timeout=10) + except queue.Empty: + asserts.fail( + f"[AttributeChangeCallback] Failed to receive a report for the {self._expected_attribute} attribute change") + + asserts.assert_equal(path.AttributeType, self._expected_attribute, + f"[AttributeChangeCallback] Received incorrect report. Expected: {self._expected_attribute}, received: {path.AttributeType}") + try: + attribute_value = transaction.GetAttribute(path) + logging.info( + f"[AttributeChangeCallback] Got attribute subscription report. Attribute {path.AttributeType}. Updated value: {attribute_value}. SubscriptionId: {transaction.subscriptionId}") + except KeyError: + asserts.fail("[AttributeChangeCallback] Attribute {expected_attribute} not found in returned report") + + class InternalTestRunnerHooks(TestRunnerHooks): def start(self, count: int): @@ -417,7 +450,13 @@ class CustomCommissioningParameters: @dataclass -class AttributePathLocation: +class ProblemLocation: + def __str__(self): + return "UNKNOWN" + + +@dataclass +class AttributePathLocation(ProblemLocation): endpoint_id: int cluster_id: Optional[int] = None attribute_id: Optional[int] = None @@ -442,7 +481,7 @@ def __str__(self): @dataclass -class EventPathLocation: +class EventPathLocation(ProblemLocation): endpoint_id: int cluster_id: int event_id: int @@ -454,7 +493,7 @@ def __str__(self): @dataclass -class CommandPathLocation: +class CommandPathLocation(ProblemLocation): endpoint_id: int cluster_id: int command_id: int @@ -466,7 +505,7 @@ def __str__(self): @dataclass -class ClusterPathLocation: +class ClusterPathLocation(ProblemLocation): endpoint_id: int cluster_id: int @@ -476,7 +515,7 @@ def __str__(self): @dataclass -class FeaturePathLocation: +class FeaturePathLocation(ProblemLocation): endpoint_id: int cluster_id: int feature_code: str @@ -500,7 +539,7 @@ class ProblemSeverity(str, Enum): @dataclass class ProblemNotice: test_name: str - location: Union[AttributePathLocation, EventPathLocation, CommandPathLocation, ClusterPathLocation, FeaturePathLocation] + location: ProblemLocation severity: ProblemSeverity problem: str spec_location: str = "" @@ -896,13 +935,13 @@ async def check_test_event_triggers_enabled(self): def print_step(self, stepnum: typing.Union[int, str], title: str) -> None: logging.info(f'***** Test Step {stepnum} : {title}') - def record_error(self, test_name: str, location: Union[AttributePathLocation, EventPathLocation, CommandPathLocation, ClusterPathLocation, FeaturePathLocation], problem: str, spec_location: str = ""): + def record_error(self, test_name: str, location: ProblemLocation, problem: str, spec_location: str = ""): self.problems.append(ProblemNotice(test_name, location, ProblemSeverity.ERROR, problem, spec_location)) - def record_warning(self, test_name: str, location: Union[AttributePathLocation, EventPathLocation, CommandPathLocation, ClusterPathLocation, FeaturePathLocation], problem: str, spec_location: str = ""): + def record_warning(self, test_name: str, location: ProblemLocation, problem: str, spec_location: str = ""): self.problems.append(ProblemNotice(test_name, location, ProblemSeverity.WARNING, problem, spec_location)) - def record_note(self, test_name: str, location: Union[AttributePathLocation, EventPathLocation, CommandPathLocation, ClusterPathLocation, FeaturePathLocation], problem: str, spec_location: str = ""): + def record_note(self, test_name: str, location: ProblemLocation, problem: str, spec_location: str = ""): self.problems.append(ProblemNotice(test_name, location, ProblemSeverity.NOTE, problem, spec_location)) def on_fail(self, record): diff --git a/src/python_testing/spec_parsing_support.py b/src/python_testing/spec_parsing_support.py index bc36049de54cd5..c2819960146ed3 100644 --- a/src/python_testing/spec_parsing_support.py +++ b/src/python_testing/spec_parsing_support.py @@ -130,7 +130,8 @@ class CommandType(Enum): 0x042F: 'RNCONC', 0x0071: 'HEPAFREMON', 0x0072: 'ACFREMON', - 0x0405: 'RH'} + 0x0405: 'RH', + 0x001C: 'PWM'} class ClusterParser: diff --git a/src/python_testing/test_testing/example_pics_xml_basic_info.xml b/src/python_testing/test_testing/example_pics_xml_basic_info.xml index 3a8e279f3aa345..3d488c3ae90ace 100644 --- a/src/python_testing/test_testing/example_pics_xml_basic_info.xml +++ b/src/python_testing/test_testing/example_pics_xml_basic_info.xml @@ -22,6 +22,14 @@ Draft O true + + + LVL.S + Does the device implement the Level Control Cluster as a server? + 9.1. Role - index.html[pdf] + O + true + @@ -182,7 +190,7 @@ Draft Does the DUT(server) support the CapabilityMinima attribute? 9.2.1. Attributes - index.html[pdf] M - true + false BINFO.S.A0014 diff --git a/src/python_testing/test_testing/test_IDM_10_4.py b/src/python_testing/test_testing/test_IDM_10_4.py new file mode 100644 index 00000000000000..8634e94129b86a --- /dev/null +++ b/src/python_testing/test_testing/test_IDM_10_4.py @@ -0,0 +1,134 @@ +#!/usr/bin/env -S python3 -B +# +# 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. +# + +import os +import sys + +import chip.clusters as Clusters +from chip.clusters import Attribute + +try: + from pics_support import parse_pics_xml +except ImportError: + sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) + from pics_support import parse_pics_xml + +from MockTestRunner import MockTestRunner + +# Reachable attribute is off in the pics file +# MaxPathsPerInvoke is not include in the pics file +# Vendor ID is included on ON in the PICS file + + +def create_read(include_reachable: bool = False, include_max_paths: bool = False, include_vendor_id: bool = True) -> Attribute.AsyncReadTransaction.ReadResponse: + # Attribute read here is set to match the example_pics_xml_basic_info.xml in this directory + bi = Clusters.BasicInformation.Attributes + lvl = Clusters.LevelControl.Attributes + attrs_bi = {bi.DataModelRevision: 1, + bi.VendorName: 'testVendor', + bi.ProductName: 'testProduct', + bi.ProductID: 0x8000, + bi.NodeLabel: 'label', + bi.Location: 'XX', + bi.HardwareVersion: 1, + bi.HardwareVersionString: 'one', + bi.SoftwareVersion: 2, + bi.SoftwareVersionString: 'two', + bi.ManufacturingDate: 'today', + bi.PartNumber: 'three', + bi.ProductURL: 'example.com', + bi.ProductLabel: 'myProduct', + bi.SerialNumber: 'ABCD1234', + bi.LocalConfigDisabled: False, + bi.UniqueID: 'Hashy-McHashface'} + if include_reachable: + attrs_bi[bi.Reachable] = True + if include_max_paths: + attrs_bi[bi.MaxPathsPerInvoke] = 2 + if include_vendor_id: + attrs_bi[bi.VendorID] = 0xFFF1 + + attrs_bi[bi.AttributeList] = [a.attribute_id for a in attrs_bi.keys()] + attrs_bi[bi.AcceptedCommandList] = [] + attrs_bi[bi.GeneratedCommandList] = [] + attrs_bi[bi.FeatureMap] = 0 + + attrs_lvl = {} + attrs_lvl[lvl.AttributeList] = [] + attrs_lvl[lvl.AcceptedCommandList] = [] + attrs_lvl[lvl.GeneratedCommandList] = [] + attrs_lvl[lvl.FeatureMap] = 0 + + resp = Attribute.AsyncReadTransaction.ReadResponse({}, [], {}) + resp.attributes = {0: {Clusters.BasicInformation: attrs_bi, Clusters.LevelControl: attrs_lvl}} + + tlv_attrs_bi = {a.attribute_id: value for a, value in attrs_bi.items()} + tlv_attrs_lvl = {a.attribute_id: value for a, value in attrs_lvl.items()} + resp.tlvAttributes = {0: {Clusters.BasicInformation.id: tlv_attrs_bi, Clusters.LevelControl.id: tlv_attrs_lvl}} + + return resp + + +def main(): + # TODO: add the same test for commands and features + script_dir = os.path.dirname(os.path.realpath(__file__)) + with open(f'{script_dir}/example_pics_xml_basic_info.xml') as f: + pics = parse_pics_xml(f.read()) + test_runner = MockTestRunner('TC_pics_checker.py', 'TC_PICS_Checker', 'test_TC_IDM_10_4', 0, pics) + failures = [] + + # Success, include vendor ID, which IS in the pics file, and neither of the incorrect ones + resp = create_read() + print(resp) + if not test_runner.run_test_with_mock_read(resp): + failures.append("Test case failure: Vendor ID included - expected pass") + + # Failure because Vendor ID is not included in the read, but included in the PICS + resp = create_read(include_vendor_id=False) + if test_runner.run_test_with_mock_read(resp): + failures.append("Test case failure: Vendor ID not included - expected failure") + + # Failure because Reachable is included in the read, but not in the PICS + resp = create_read(include_reachable=True) + if test_runner.run_test_with_mock_read(resp): + failures.append("Test case failure: Reachable included but not in PICS- expected failure") + + # Failure because MaxPathsPerInvoke is included in the read, but not in the PICS + resp = create_read(include_max_paths=True) + if test_runner.run_test_with_mock_read(resp): + failures.append("Test case failure: MaxPathsPerInvoke included but not in PICS- expected failure") + + pics['PICS_SDK_CI_ONLY'] = True + test_runner.config.pics = pics + # This is a success case for the attributes (as seen above), but the test should fail because the CI PICS is added + resp = create_read() + if test_runner.run_test_with_mock_read(resp): + failures.append("Test case failure: SDK CI PICS is included - expected failure") + + test_runner.Shutdown() + + print( + f"Test of tests: PICS - test response incorrect: {len(failures)}") + for f in failures: + print(f) + + return 1 if failures else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/tracing/json/json_tracing.cpp b/src/tracing/json/json_tracing.cpp index 91b4474388ecd0..4531740b81a193 100644 --- a/src/tracing/json/json_tracing.cpp +++ b/src/tracing/json/json_tracing.cpp @@ -418,8 +418,9 @@ void JsonBackend::LogNodeDiscovered(NodeDiscoveredInfo & info) info.result->address.ToString(address_buff); - result["supports_tcp"] = info.result->supportsTcp; - result["address"] = address_buff; + result["supports_tcp_client"] = info.result->supportsTcpClient; + result["supports_tcp_server"] = info.result->supportsTcpServer; + result["address"] = address_buff; result["mrp"]["idle_retransmit_timeout_ms"] = info.result->mrpRemoteConfig.mIdleRetransTimeout.count(); result["mrp"]["active_retransmit_timeout_ms"] = info.result->mrpRemoteConfig.mActiveRetransTimeout.count(); diff --git a/src/tracing/tests/BUILD.gn b/src/tracing/tests/BUILD.gn index fcb9bc2810544d..e44bb6b14cf741 100644 --- a/src/tracing/tests/BUILD.gn +++ b/src/tracing/tests/BUILD.gn @@ -14,6 +14,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") import("${chip_root}/build/chip/chip_test_suite.gni") import("${chip_root}/src/tracing/tracing_args.gni") diff --git a/src/tracing/tests/TestMetricEvents.cpp b/src/tracing/tests/TestMetricEvents.cpp index a0190265d57e0b..01c2c6e5a93eeb 100644 --- a/src/tracing/tests/TestMetricEvents.cpp +++ b/src/tracing/tests/TestMetricEvents.cpp @@ -13,7 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include +#include + +#include #include #include diff --git a/src/tracing/tests/TestTracing.cpp b/src/tracing/tests/TestTracing.cpp index 254c6de5c78cb7..fa519a02163cbe 100644 --- a/src/tracing/tests/TestTracing.cpp +++ b/src/tracing/tests/TestTracing.cpp @@ -13,7 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include +#include + +#include #include #include #include diff --git a/src/transport/tests/TestSessionManagerDispatch.cpp b/src/transport/tests/TestSessionManagerDispatch.cpp index f90cb0fa2b21ac..3ef66057adfbc8 100644 --- a/src/transport/tests/TestSessionManagerDispatch.cpp +++ b/src/transport/tests/TestSessionManagerDispatch.cpp @@ -36,7 +36,7 @@ #include #include -#include +#include #include diff --git a/third_party/silabs/SiWx917_sdk.gni b/third_party/silabs/SiWx917_sdk.gni index a7bfe1456c0b4d..5faba08acd3d3b 100644 --- a/third_party/silabs/SiWx917_sdk.gni +++ b/third_party/silabs/SiWx917_sdk.gni @@ -291,14 +291,20 @@ template("siwx917_sdk") { if (invoker.enable_dic) { _include_dirs += [ "${chip_root}/third_party/silabs/mqtt/stack" ] } + + if (chip_enable_icd_server || !disable_lcd) { + defines += [ + "SL_SLEEP_TIMER=1", + "SI91X_SYSRTC_COUNT=1", + ] + } + if (!disable_lcd) { defines += [ "CONFIG_ENABLE_UART", - "SI91X_SYSRTC_COUNT=1", "SYSCALLS_WRITE", "SPI_MULTI_SLAVE", "SL_ULP_TIMER", - "SL_SLEEP_TIMER", ] } @@ -755,6 +761,14 @@ template("siwx917_sdk") { ] } + if (chip_enable_icd_server || !disable_lcd) { + sources += [ + "${efr32_sdk_root}/platform/service/sleeptimer/src/sl_sleeptimer.c", + "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_sysrtc.c", + "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/service/sleeptimer/src/sl_sleeptimer_hal_si91x_sysrtc.c", + ] + } + if (!disable_lcd) { sources += [ "${efr32_sdk_root}/platform/middleware/glib/dmd/display/dmd_memlcd.c", @@ -769,13 +783,10 @@ template("siwx917_sdk") { "${efr32_sdk_root}/platform/middleware/glib/glib/glib_polygon.c", "${efr32_sdk_root}/platform/middleware/glib/glib/glib_rectangle.c", "${efr32_sdk_root}/platform/middleware/glib/glib/glib_string.c", - "${efr32_sdk_root}/platform/service/sleeptimer/src/sl_sleeptimer.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/cmsis_driver/SPI.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/memlcd/src/memlcd_917/sl_memlcd_spi.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/memlcd/src/sl_memlcd.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/memlcd/src/sl_memlcd_display.c", - "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_sysrtc.c", - "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/service/sleeptimer/src/sl_sleeptimer_hal_si91x_sysrtc.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/unified_api/src/sl_si91x_ulp_timer.c", ] } diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index e349271c1d9ed5..5ea642c2490387 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -15001,6 +15001,395 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace Attributes } // namespace ElectricalEnergyMeasurement +namespace WaterHeaterManagement { +namespace Attributes { + +namespace HeaterTypes { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, + chip::BitMask * value) +{ + using Traits = NumericAttributeTraits>; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::BitMask value, + MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits>; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE, + markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::BitMask value) +{ + using Traits = NumericAttributeTraits>; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE); +} + +} // namespace HeaterTypes + +namespace HeatDemand { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, + chip::BitMask * value) +{ + using Traits = NumericAttributeTraits>; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::BitMask value, + MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits>; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE, + markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::BitMask value) +{ + using Traits = NumericAttributeTraits>; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE); +} + +} // namespace HeatDemand + +namespace TankVolume { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace TankVolume + +namespace EstimatedHeatRequired { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, int64_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int64_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_ENERGY_MWH_ATTRIBUTE_TYPE, + markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int64_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_ENERGY_MWH_ATTRIBUTE_TYPE); +} + +} // namespace EstimatedHeatRequired + +namespace TankPercentage { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::Percent * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::Percent value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE, + markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::Percent value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE); +} + +} // namespace TankPercentage + +namespace BoostState { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, + chip::app::Clusters::WaterHeaterManagement::BoostStateEnum * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::WaterHeaterManagement::BoostStateEnum value, + MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::WaterHeaterManagement::BoostStateEnum value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); +} + +} // namespace BoostState + +namespace FeatureMap { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, + markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); +} + +} // namespace FeatureMap + +namespace ClusterRevision { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace WaterHeaterManagement + namespace DemandResponseLoadControl { namespace Attributes { @@ -38256,6 +38645,154 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace Attributes } // namespace ContentAppObserver +namespace CommissionerControl { +namespace Attributes { + +namespace SupportedDeviceCategories { + +Protocols::InteractionModel::Status +Get(chip::EndpointId endpoint, chip::BitMask * value) +{ + using Traits = NumericAttributeTraits>; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::CommissionerControl::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status +Set(chip::EndpointId endpoint, chip::BitMask value, + MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits>; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::CommissionerControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status +Set(chip::EndpointId endpoint, chip::BitMask value) +{ + using Traits = NumericAttributeTraits>; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::CommissionerControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); +} + +} // namespace SupportedDeviceCategories + +namespace FeatureMap { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::CommissionerControl::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::CommissionerControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::CommissionerControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); +} + +} // namespace FeatureMap + +namespace ClusterRevision { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::CommissionerControl::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::CommissionerControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::CommissionerControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace CommissionerControl + namespace ElectricalMeasurement { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index acf4ff18b97443..2e9f20115c2738 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -2467,6 +2467,73 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace Attributes } // namespace ElectricalEnergyMeasurement +namespace WaterHeaterManagement { +namespace Attributes { + +namespace HeaterTypes { +Protocols::InteractionModel::Status +Get(chip::EndpointId endpoint, + chip::BitMask * value); // WaterHeaterTypeBitmap +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::BitMask value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::BitMask value, + MarkAttributeDirty markDirty); +} // namespace HeaterTypes + +namespace HeatDemand { +Protocols::InteractionModel::Status +Get(chip::EndpointId endpoint, + chip::BitMask * value); // WaterHeaterDemandBitmap +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::BitMask value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::BitMask value, + MarkAttributeDirty markDirty); +} // namespace HeatDemand + +namespace TankVolume { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); +} // namespace TankVolume + +namespace EstimatedHeatRequired { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, int64_t * value); // energy_mwh +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int64_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int64_t value, MarkAttributeDirty markDirty); +} // namespace EstimatedHeatRequired + +namespace TankPercentage { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::Percent * value); // percent +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::Percent value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::Percent value, MarkAttributeDirty markDirty); +} // namespace TankPercentage + +namespace BoostState { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, + chip::app::Clusters::WaterHeaterManagement::BoostStateEnum * value); // BoostStateEnum +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::app::Clusters::WaterHeaterManagement::BoostStateEnum value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::WaterHeaterManagement::BoostStateEnum value, + MarkAttributeDirty markDirty); +} // namespace BoostState + +namespace FeatureMap { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); +} // namespace FeatureMap + +namespace ClusterRevision { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace WaterHeaterManagement + namespace DemandResponseLoadControl { namespace Attributes { @@ -5894,6 +5961,35 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace Attributes } // namespace ContentAppObserver +namespace CommissionerControl { +namespace Attributes { + +namespace SupportedDeviceCategories { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, + chip::BitMask * + value); // SupportedDeviceCategoryBitmap +Protocols::InteractionModel::Status +Set(chip::EndpointId endpoint, chip::BitMask value); +Protocols::InteractionModel::Status +Set(chip::EndpointId endpoint, chip::BitMask value, + MarkAttributeDirty markDirty); +} // namespace SupportedDeviceCategories + +namespace FeatureMap { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); +} // namespace FeatureMap + +namespace ClusterRevision { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace CommissionerControl + namespace ElectricalMeasurement { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/callback.h b/zzz_generated/app-common/app-common/zap-generated/callback.h index 104f2a09bfb362..7be9f882fd37ef 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -368,6 +368,11 @@ void emberAfElectricalPowerMeasurementClusterInitCallback(chip::EndpointId endpo */ void emberAfElectricalEnergyMeasurementClusterInitCallback(chip::EndpointId endpoint); +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfWaterHeaterManagementClusterInitCallback(chip::EndpointId endpoint); + /** * @param endpoint Endpoint that is being initialized */ @@ -623,6 +628,11 @@ void emberAfContentControlClusterInitCallback(chip::EndpointId endpoint); */ void emberAfContentAppObserverClusterInitCallback(chip::EndpointId endpoint); +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfCommissionerControlClusterInitCallback(chip::EndpointId endpoint); + /** * @param endpoint Endpoint that is being initialized */ @@ -3230,6 +3240,44 @@ chip::Protocols::InteractionModel::Status MatterElectricalEnergyMeasurementClust */ void emberAfElectricalEnergyMeasurementClusterServerTickCallback(chip::EndpointId endpoint); +// +// Water Heater Management Cluster +// + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfWaterHeaterManagementClusterServerInitCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being shutdown + */ +void MatterWaterHeaterManagementClusterServerShutdownCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfWaterHeaterManagementClusterClientInitCallback(chip::EndpointId endpoint); + +/** + * @param attributePath Concrete attribute path that changed + */ +void MatterWaterHeaterManagementClusterServerAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath); + +/** + * @param attributePath Concrete attribute path to be changed + * @param attributeType Attribute type + * @param size Attribute size + * @param value Attribute value + */ +chip::Protocols::InteractionModel::Status MatterWaterHeaterManagementClusterServerPreAttributeChangedCallback( + const chip::app::ConcreteAttributePath & attributePath, EmberAfAttributeType attributeType, uint16_t size, uint8_t * value); + +/** + * @param endpoint Endpoint that is being served + */ +void emberAfWaterHeaterManagementClusterServerTickCallback(chip::EndpointId endpoint); + // // Demand Response Load Control Cluster // @@ -5206,6 +5254,44 @@ chip::Protocols::InteractionModel::Status MatterContentAppObserverClusterServerP */ void emberAfContentAppObserverClusterServerTickCallback(chip::EndpointId endpoint); +// +// Commissioner Control Cluster +// + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfCommissionerControlClusterServerInitCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being shutdown + */ +void MatterCommissionerControlClusterServerShutdownCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfCommissionerControlClusterClientInitCallback(chip::EndpointId endpoint); + +/** + * @param attributePath Concrete attribute path that changed + */ +void MatterCommissionerControlClusterServerAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath); + +/** + * @param attributePath Concrete attribute path to be changed + * @param attributeType Attribute type + * @param size Attribute size + * @param value Attribute value + */ +chip::Protocols::InteractionModel::Status MatterCommissionerControlClusterServerPreAttributeChangedCallback( + const chip::app::ConcreteAttributePath & attributePath, EmberAfAttributeType attributeType, uint16_t size, uint8_t * value); + +/** + * @param endpoint Endpoint that is being served + */ +void emberAfCommissionerControlClusterServerTickCallback(chip::EndpointId endpoint); + // // Electrical Measurement Cluster // @@ -5880,6 +5966,18 @@ bool emberAfValveConfigurationAndControlClusterOpenCallback( bool emberAfValveConfigurationAndControlClusterCloseCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::ValveConfigurationAndControl::Commands::Close::DecodableType & commandData); +/** + * @brief Water Heater Management Cluster Boost Command callback (from client) + */ +bool emberAfWaterHeaterManagementClusterBoostCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::WaterHeaterManagement::Commands::Boost::DecodableType & commandData); +/** + * @brief Water Heater Management Cluster CancelBoost Command callback (from client) + */ +bool emberAfWaterHeaterManagementClusterCancelBoostCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::WaterHeaterManagement::Commands::CancelBoost::DecodableType & commandData); /** * @brief Demand Response Load Control Cluster RegisterLoadControlProgramRequest Command callback (from client) */ @@ -6630,6 +6728,18 @@ bool emberAfContentControlClusterSetScheduledContentRatingThresholdCallback( bool emberAfContentAppObserverClusterContentAppMessageCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessage::DecodableType & commandData); +/** + * @brief Commissioner Control Cluster RequestCommissioningApproval Command callback (from client) + */ +bool emberAfCommissionerControlClusterRequestCommissioningApprovalCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::DecodableType & commandData); +/** + * @brief Commissioner Control Cluster CommissionNode Command callback (from client) + */ +bool emberAfCommissionerControlClusterCommissionNodeCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::CommissionerControl::Commands::CommissionNode::DecodableType & commandData); /** * @brief Electrical Measurement Cluster GetProfileInfoCommand Command callback (from client) */ diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h index 7e52fd09a2c13c..0304b683406b8b 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h @@ -1572,6 +1572,19 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(ElectricalPowerMeasurem } } +static auto __attribute__((unused)) EnsureKnownEnumValue(WaterHeaterManagement::BoostStateEnum val) +{ + using EnumType = WaterHeaterManagement::BoostStateEnum; + switch (val) + { + case EnumType::kInactive: + case EnumType::kActive: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} + static auto __attribute__((unused)) EnsureKnownEnumValue(DemandResponseLoadControl::CriticalityLevelEnum val) { using EnumType = DemandResponseLoadControl::CriticalityLevelEnum; @@ -1860,6 +1873,7 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(EnergyEvse::SupplyState case EnumType::kDischargingEnabled: case EnumType::kDisabledError: case EnumType::kDisabledDiagnostics: + case EnumType::kEnabled: return val; default: return EnumType::kUnknownEnumValue; diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h index 52e953741808d1..37562af207838f 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h @@ -2299,6 +2299,48 @@ enum class Feature : uint32_t }; } // namespace ElectricalEnergyMeasurement +namespace WaterHeaterManagement { + +// Enum for BoostStateEnum +enum class BoostStateEnum : uint8_t +{ + kInactive = 0x00, + kActive = 0x01, + // All received enum values that are not listed above will be mapped + // to kUnknownEnumValue. This is a helper enum value that should only + // be used by code to process how it handles receiving and unknown + // enum value. This specific should never be transmitted. + kUnknownEnumValue = 2, +}; + +// Bitmap for Feature +enum class Feature : uint32_t +{ + kEnergyManagement = 0x1, + kTankPercent = 0x2, +}; + +// Bitmap for WaterHeaterDemandBitmap +enum class WaterHeaterDemandBitmap : uint8_t +{ + kImmersionElement1 = 0x1, + kImmersionElement2 = 0x2, + kHeatPump = 0x4, + kBoiler = 0x8, + kOther = 0x10, +}; + +// Bitmap for WaterHeaterTypeBitmap +enum class WaterHeaterTypeBitmap : uint8_t +{ + kImmersionElement1 = 0x1, + kImmersionElement2 = 0x2, + kHeatPump = 0x4, + kBoiler = 0x8, + kOther = 0x10, +}; +} // namespace WaterHeaterManagement + namespace DemandResponseLoadControl { // Enum for CriticalityLevelEnum @@ -2677,11 +2719,12 @@ enum class SupplyStateEnum : uint8_t kDischargingEnabled = 0x02, kDisabledError = 0x03, kDisabledDiagnostics = 0x04, + kEnabled = 0x05, // All received enum values that are not listed above will be mapped // to kUnknownEnumValue. This is a helper enum value that should only // be used by code to process how it handles receiving and unknown // enum value. This specific should never be transmitted. - kUnknownEnumValue = 5, + kUnknownEnumValue = 6, }; // Bitmap for Feature @@ -5133,6 +5176,15 @@ enum class StatusEnum : uint8_t }; } // namespace ContentAppObserver +namespace CommissionerControl { + +// Bitmap for SupportedDeviceCategoryBitmap +enum class SupportedDeviceCategoryBitmap : uint32_t +{ + kFabricSynchronization = 0x1, +}; +} // namespace CommissionerControl + namespace ElectricalMeasurement {} // namespace ElectricalMeasurement namespace UnitTesting { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index 09383b5a02c3ec..d821d185f11272 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -14550,6 +14550,128 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } // namespace Events } // namespace ElectricalEnergyMeasurement +namespace WaterHeaterManagement { + +namespace Commands { +namespace Boost { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kDuration), duration); + encoder.Encode(to_underlying(Fields::kOneShot), oneShot); + encoder.Encode(to_underlying(Fields::kEmergencyBoost), emergencyBoost); + encoder.Encode(to_underlying(Fields::kTemporarySetpoint), temporarySetpoint); + encoder.Encode(to_underlying(Fields::kTargetPercentage), targetPercentage); + encoder.Encode(to_underlying(Fields::kTargetReheat), targetReheat); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kDuration)) + { + err = DataModel::Decode(reader, duration); + } + else if (__context_tag == to_underlying(Fields::kOneShot)) + { + err = DataModel::Decode(reader, oneShot); + } + else if (__context_tag == to_underlying(Fields::kEmergencyBoost)) + { + err = DataModel::Decode(reader, emergencyBoost); + } + else if (__context_tag == to_underlying(Fields::kTemporarySetpoint)) + { + err = DataModel::Decode(reader, temporarySetpoint); + } + else if (__context_tag == to_underlying(Fields::kTargetPercentage)) + { + err = DataModel::Decode(reader, targetPercentage); + } + else if (__context_tag == to_underlying(Fields::kTargetReheat)) + { + err = DataModel::Decode(reader, targetReheat); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace Boost. +namespace CancelBoost { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + } +} +} // namespace CancelBoost. +} // namespace Commands + +namespace Attributes { +CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path) +{ + switch (path.mAttributeId) + { + case Attributes::HeaterTypes::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, heaterTypes); + case Attributes::HeatDemand::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, heatDemand); + case Attributes::TankVolume::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, tankVolume); + case Attributes::EstimatedHeatRequired::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, estimatedHeatRequired); + case Attributes::TankPercentage::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, tankPercentage); + case Attributes::BoostState::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, boostState); + case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, generatedCommandList); + case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, acceptedCommandList); + case Attributes::EventList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, eventList); + case Attributes::AttributeList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, attributeList); + case Attributes::FeatureMap::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, featureMap); + case Attributes::ClusterRevision::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, clusterRevision); + default: + return CHIP_NO_ERROR; + } +} +} // namespace Attributes + +namespace Events {} // namespace Events + +} // namespace WaterHeaterManagement namespace DemandResponseLoadControl { namespace Structs { @@ -16964,6 +17086,7 @@ CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kSessionID), sessionID)); ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kState), state)); ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kMaximumCurrent), maximumCurrent)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kMaximumDischargeCurrent), maximumDischargeCurrent)); return aWriter.EndContainer(outer); } @@ -16993,6 +17116,10 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) { err = DataModel::Decode(reader, maximumCurrent); } + else if (__context_tag == to_underlying(Fields::kMaximumDischargeCurrent)) + { + err = DataModel::Decode(reader, maximumDischargeCurrent); + } else { } @@ -17010,6 +17137,7 @@ CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kState), state)); ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kReason), reason)); ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kEnergyTransferred), energyTransferred)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kEnergyDischarged), energyDischarged)); return aWriter.EndContainer(outer); } @@ -17043,6 +17171,10 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) { err = DataModel::Decode(reader, energyTransferred); } + else if (__context_tag == to_underlying(Fields::kEnergyDischarged)) + { + err = DataModel::Decode(reader, energyDischarged); + } else { } @@ -27815,6 +27947,242 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre namespace Events {} // namespace Events } // namespace ContentAppObserver +namespace CommissionerControl { + +namespace Commands { +namespace RequestCommissioningApproval { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kRequestId), requestId); + encoder.Encode(to_underlying(Fields::kVendorId), vendorId); + encoder.Encode(to_underlying(Fields::kProductId), productId); + encoder.Encode(to_underlying(Fields::kLabel), label); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kRequestId)) + { + err = DataModel::Decode(reader, requestId); + } + else if (__context_tag == to_underlying(Fields::kVendorId)) + { + err = DataModel::Decode(reader, vendorId); + } + else if (__context_tag == to_underlying(Fields::kProductId)) + { + err = DataModel::Decode(reader, productId); + } + else if (__context_tag == to_underlying(Fields::kLabel)) + { + err = DataModel::Decode(reader, label); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace RequestCommissioningApproval. +namespace CommissionNode { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kRequestId), requestId); + encoder.Encode(to_underlying(Fields::kResponseTimeoutSeconds), responseTimeoutSeconds); + encoder.Encode(to_underlying(Fields::kIpAddress), ipAddress); + encoder.Encode(to_underlying(Fields::kPort), port); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kRequestId)) + { + err = DataModel::Decode(reader, requestId); + } + else if (__context_tag == to_underlying(Fields::kResponseTimeoutSeconds)) + { + err = DataModel::Decode(reader, responseTimeoutSeconds); + } + else if (__context_tag == to_underlying(Fields::kIpAddress)) + { + err = DataModel::Decode(reader, ipAddress); + } + else if (__context_tag == to_underlying(Fields::kPort)) + { + err = DataModel::Decode(reader, port); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace CommissionNode. +namespace ReverseOpenCommissioningWindow { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kCommissioningTimeout), commissioningTimeout); + encoder.Encode(to_underlying(Fields::kPAKEPasscodeVerifier), PAKEPasscodeVerifier); + encoder.Encode(to_underlying(Fields::kDiscriminator), discriminator); + encoder.Encode(to_underlying(Fields::kIterations), iterations); + encoder.Encode(to_underlying(Fields::kSalt), salt); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kCommissioningTimeout)) + { + err = DataModel::Decode(reader, commissioningTimeout); + } + else if (__context_tag == to_underlying(Fields::kPAKEPasscodeVerifier)) + { + err = DataModel::Decode(reader, PAKEPasscodeVerifier); + } + else if (__context_tag == to_underlying(Fields::kDiscriminator)) + { + err = DataModel::Decode(reader, discriminator); + } + else if (__context_tag == to_underlying(Fields::kIterations)) + { + err = DataModel::Decode(reader, iterations); + } + else if (__context_tag == to_underlying(Fields::kSalt)) + { + err = DataModel::Decode(reader, salt); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace ReverseOpenCommissioningWindow. +} // namespace Commands + +namespace Attributes { +CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path) +{ + switch (path.mAttributeId) + { + case Attributes::SupportedDeviceCategories::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, supportedDeviceCategories); + case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, generatedCommandList); + case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, acceptedCommandList); + case Attributes::EventList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, eventList); + case Attributes::AttributeList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, attributeList); + case Attributes::FeatureMap::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, featureMap); + case Attributes::ClusterRevision::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, clusterRevision); + default: + return CHIP_NO_ERROR; + } +} +} // namespace Attributes + +namespace Events { +namespace CommissioningRequestResult { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + TLV::TLVType outer; + ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outer)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kRequestId), requestId)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kClientNodeId), clientNodeId)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kStatusCode), statusCode)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kFabricIndex), fabricIndex)); + return aWriter.EndContainer(outer); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kRequestId)) + { + err = DataModel::Decode(reader, requestId); + } + else if (__context_tag == to_underlying(Fields::kClientNodeId)) + { + err = DataModel::Decode(reader, clientNodeId); + } + else if (__context_tag == to_underlying(Fields::kStatusCode)) + { + err = DataModel::Decode(reader, statusCode); + } + else if (__context_tag == to_underlying(Fields::kFabricIndex)) + { + err = DataModel::Decode(reader, fabricIndex); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace CommissioningRequestResult. +} // namespace Events + +} // namespace CommissionerControl namespace ElectricalMeasurement { namespace Commands { @@ -31421,6 +31789,13 @@ bool CommandIsFabricScoped(ClusterId aCluster, CommandId aCommand) return false; } } + case Clusters::WaterHeaterManagement::Id: { + switch (aCommand) + { + default: + return false; + } + } case Clusters::DemandResponseLoadControl::Id: { switch (aCommand) { @@ -31627,6 +32002,13 @@ bool CommandIsFabricScoped(ClusterId aCluster, CommandId aCommand) return false; } } + case Clusters::CommissionerControl::Id: { + switch (aCommand) + { + default: + return false; + } + } case Clusters::ElectricalMeasurement::Id: { switch (aCommand) { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index 5b562f5b58a020..a32e52a5c072f8 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -20836,6 +20836,239 @@ struct DecodableType } // namespace PeriodicEnergyMeasured } // namespace Events } // namespace ElectricalEnergyMeasurement +namespace WaterHeaterManagement { + +namespace Commands { +// Forward-declarations so we can reference these later. + +namespace Boost { +struct Type; +struct DecodableType; +} // namespace Boost + +namespace CancelBoost { +struct Type; +struct DecodableType; +} // namespace CancelBoost + +} // namespace Commands + +namespace Commands { +namespace Boost { +enum class Fields : uint8_t +{ + kDuration = 0, + kOneShot = 1, + kEmergencyBoost = 2, + kTemporarySetpoint = 3, + kTargetPercentage = 4, + kTargetReheat = 5, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::Boost::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } + + uint32_t duration = static_cast(0); + Optional oneShot; + Optional emergencyBoost; + Optional temporarySetpoint; + Optional targetPercentage; + Optional targetReheat; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::Boost::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } + + uint32_t duration = static_cast(0); + Optional oneShot; + Optional emergencyBoost; + Optional temporarySetpoint; + Optional targetPercentage; + Optional targetReheat; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace Boost +namespace CancelBoost { +enum class Fields : uint8_t +{ +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::CancelBoost::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::CancelBoost::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace CancelBoost +} // namespace Commands + +namespace Attributes { + +namespace HeaterTypes { +struct TypeInfo +{ + using Type = chip::BitMask; + using DecodableType = chip::BitMask; + using DecodableArgType = chip::BitMask; + + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::HeaterTypes::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace HeaterTypes +namespace HeatDemand { +struct TypeInfo +{ + using Type = chip::BitMask; + using DecodableType = chip::BitMask; + using DecodableArgType = chip::BitMask; + + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::HeatDemand::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace HeatDemand +namespace TankVolume { +struct TypeInfo +{ + using Type = uint16_t; + using DecodableType = uint16_t; + using DecodableArgType = uint16_t; + + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::TankVolume::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace TankVolume +namespace EstimatedHeatRequired { +struct TypeInfo +{ + using Type = int64_t; + using DecodableType = int64_t; + using DecodableArgType = int64_t; + + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::EstimatedHeatRequired::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace EstimatedHeatRequired +namespace TankPercentage { +struct TypeInfo +{ + using Type = chip::Percent; + using DecodableType = chip::Percent; + using DecodableArgType = chip::Percent; + + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::TankPercentage::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace TankPercentage +namespace BoostState { +struct TypeInfo +{ + using Type = chip::app::Clusters::WaterHeaterManagement::BoostStateEnum; + using DecodableType = chip::app::Clusters::WaterHeaterManagement::BoostStateEnum; + using DecodableArgType = chip::app::Clusters::WaterHeaterManagement::BoostStateEnum; + + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::BoostState::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace BoostState +namespace GeneratedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } +}; +} // namespace GeneratedCommandList +namespace AcceptedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } +}; +} // namespace AcceptedCommandList +namespace EventList { +struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } +}; +} // namespace EventList +namespace AttributeList { +struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } +}; +} // namespace AttributeList +namespace FeatureMap { +struct TypeInfo : public Clusters::Globals::Attributes::FeatureMap::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } +}; +} // namespace FeatureMap +namespace ClusterRevision { +struct TypeInfo : public Clusters::Globals::Attributes::ClusterRevision::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } +}; +} // namespace ClusterRevision + +struct TypeInfo +{ + struct DecodableType + { + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); + + Attributes::HeaterTypes::TypeInfo::DecodableType heaterTypes = + static_cast>(0); + Attributes::HeatDemand::TypeInfo::DecodableType heatDemand = + static_cast>(0); + Attributes::TankVolume::TypeInfo::DecodableType tankVolume = static_cast(0); + Attributes::EstimatedHeatRequired::TypeInfo::DecodableType estimatedHeatRequired = static_cast(0); + Attributes::TankPercentage::TypeInfo::DecodableType tankPercentage = static_cast(0); + Attributes::BoostState::TypeInfo::DecodableType boostState = + static_cast(0); + Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; + Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; + Attributes::EventList::TypeInfo::DecodableType eventList; + Attributes::AttributeList::TypeInfo::DecodableType attributeList; + Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); + Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); + }; +}; +} // namespace Attributes +} // namespace WaterHeaterManagement namespace DemandResponseLoadControl { namespace Structs { namespace HeatingSourceControlStruct { @@ -23532,9 +23765,10 @@ static constexpr PriorityLevel kPriorityLevel = PriorityLevel::Info; enum class Fields : uint8_t { - kSessionID = 0, - kState = 1, - kMaximumCurrent = 2, + kSessionID = 0, + kState = 1, + kMaximumCurrent = 2, + kMaximumDischargeCurrent = 3, }; struct Type @@ -23548,6 +23782,7 @@ struct Type uint32_t sessionID = static_cast(0); StateEnum state = static_cast(0); int64_t maximumCurrent = static_cast(0); + Optional maximumDischargeCurrent; CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; }; @@ -23562,6 +23797,7 @@ struct DecodableType uint32_t sessionID = static_cast(0); StateEnum state = static_cast(0); int64_t maximumCurrent = static_cast(0); + Optional maximumDischargeCurrent; CHIP_ERROR Decode(TLV::TLVReader & reader); }; @@ -23575,6 +23811,7 @@ enum class Fields : uint8_t kState = 1, kReason = 2, kEnergyTransferred = 4, + kEnergyDischarged = 5, }; struct Type @@ -23589,6 +23826,7 @@ struct Type StateEnum state = static_cast(0); EnergyTransferStoppedReasonEnum reason = static_cast(0); int64_t energyTransferred = static_cast(0); + Optional energyDischarged; CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; }; @@ -23604,6 +23842,7 @@ struct DecodableType StateEnum state = static_cast(0); EnergyTransferStoppedReasonEnum reason = static_cast(0); int64_t energyTransferred = static_cast(0); + Optional energyDischarged; CHIP_ERROR Decode(TLV::TLVReader & reader); }; @@ -40750,6 +40989,274 @@ struct TypeInfo }; } // namespace Attributes } // namespace ContentAppObserver +namespace CommissionerControl { + +namespace Commands { +// Forward-declarations so we can reference these later. + +namespace RequestCommissioningApproval { +struct Type; +struct DecodableType; +} // namespace RequestCommissioningApproval + +namespace CommissionNode { +struct Type; +struct DecodableType; +} // namespace CommissionNode + +namespace ReverseOpenCommissioningWindow { +struct Type; +struct DecodableType; +} // namespace ReverseOpenCommissioningWindow + +} // namespace Commands + +namespace Commands { +namespace RequestCommissioningApproval { +enum class Fields : uint8_t +{ + kRequestId = 0, + kVendorId = 1, + kProductId = 2, + kLabel = 3, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::RequestCommissioningApproval::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + uint64_t requestId = static_cast(0); + chip::VendorId vendorId = static_cast(0); + uint16_t productId = static_cast(0); + Optional label; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::RequestCommissioningApproval::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + uint64_t requestId = static_cast(0); + chip::VendorId vendorId = static_cast(0); + uint16_t productId = static_cast(0); + Optional label; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace RequestCommissioningApproval +namespace CommissionNode { +enum class Fields : uint8_t +{ + kRequestId = 0, + kResponseTimeoutSeconds = 1, + kIpAddress = 2, + kPort = 3, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::CommissionNode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + uint64_t requestId = static_cast(0); + uint16_t responseTimeoutSeconds = static_cast(0); + Optional ipAddress; + Optional port; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::CommissionNode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + uint64_t requestId = static_cast(0); + uint16_t responseTimeoutSeconds = static_cast(0); + Optional ipAddress; + Optional port; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace CommissionNode +namespace ReverseOpenCommissioningWindow { +enum class Fields : uint8_t +{ + kCommissioningTimeout = 0, + kPAKEPasscodeVerifier = 1, + kDiscriminator = 2, + kIterations = 3, + kSalt = 4, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::ReverseOpenCommissioningWindow::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + uint16_t commissioningTimeout = static_cast(0); + chip::ByteSpan PAKEPasscodeVerifier; + uint16_t discriminator = static_cast(0); + uint32_t iterations = static_cast(0); + chip::ByteSpan salt; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::ReverseOpenCommissioningWindow::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + uint16_t commissioningTimeout = static_cast(0); + chip::ByteSpan PAKEPasscodeVerifier; + uint16_t discriminator = static_cast(0); + uint32_t iterations = static_cast(0); + chip::ByteSpan salt; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace ReverseOpenCommissioningWindow +} // namespace Commands + +namespace Attributes { + +namespace SupportedDeviceCategories { +struct TypeInfo +{ + using Type = chip::BitMask; + using DecodableType = chip::BitMask; + using DecodableArgType = chip::BitMask; + + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::SupportedDeviceCategories::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace SupportedDeviceCategories +namespace GeneratedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } +}; +} // namespace GeneratedCommandList +namespace AcceptedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } +}; +} // namespace AcceptedCommandList +namespace EventList { +struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } +}; +} // namespace EventList +namespace AttributeList { +struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } +}; +} // namespace AttributeList +namespace FeatureMap { +struct TypeInfo : public Clusters::Globals::Attributes::FeatureMap::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } +}; +} // namespace FeatureMap +namespace ClusterRevision { +struct TypeInfo : public Clusters::Globals::Attributes::ClusterRevision::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } +}; +} // namespace ClusterRevision + +struct TypeInfo +{ + struct DecodableType + { + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); + + Attributes::SupportedDeviceCategories::TypeInfo::DecodableType supportedDeviceCategories = + static_cast>(0); + Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; + Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; + Attributes::EventList::TypeInfo::DecodableType eventList; + Attributes::AttributeList::TypeInfo::DecodableType attributeList; + Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); + Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); + }; +}; +} // namespace Attributes +namespace Events { +namespace CommissioningRequestResult { +static constexpr PriorityLevel kPriorityLevel = PriorityLevel::Info; + +enum class Fields : uint8_t +{ + kRequestId = 0, + kClientNodeId = 1, + kStatusCode = 2, + kFabricIndex = 254, +}; + +struct Type +{ +public: + static constexpr PriorityLevel GetPriorityLevel() { return kPriorityLevel; } + static constexpr EventId GetEventId() { return Events::CommissioningRequestResult::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + static constexpr bool kIsFabricScoped = true; + + uint64_t requestId = static_cast(0); + chip::NodeId clientNodeId = static_cast(0); + uint8_t statusCode = static_cast(0); + chip::FabricIndex fabricIndex = static_cast(0); + + auto GetFabricIndex() const { return fabricIndex; } + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +struct DecodableType +{ +public: + static constexpr PriorityLevel GetPriorityLevel() { return kPriorityLevel; } + static constexpr EventId GetEventId() { return Events::CommissioningRequestResult::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + uint64_t requestId = static_cast(0); + chip::NodeId clientNodeId = static_cast(0); + uint8_t statusCode = static_cast(0); + chip::FabricIndex fabricIndex = static_cast(0); + + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +} // namespace CommissioningRequestResult +} // namespace Events +} // namespace CommissionerControl namespace ElectricalMeasurement { namespace Commands { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h index 7bfad24bf56998..b025f1ccf57811 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h @@ -3801,6 +3801,60 @@ static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; } // namespace Attributes } // namespace ElectricalEnergyMeasurement +namespace WaterHeaterManagement { +namespace Attributes { + +namespace HeaterTypes { +static constexpr AttributeId Id = 0x00000000; +} // namespace HeaterTypes + +namespace HeatDemand { +static constexpr AttributeId Id = 0x00000001; +} // namespace HeatDemand + +namespace TankVolume { +static constexpr AttributeId Id = 0x00000002; +} // namespace TankVolume + +namespace EstimatedHeatRequired { +static constexpr AttributeId Id = 0x00000003; +} // namespace EstimatedHeatRequired + +namespace TankPercentage { +static constexpr AttributeId Id = 0x00000004; +} // namespace TankPercentage + +namespace BoostState { +static constexpr AttributeId Id = 0x00000005; +} // namespace BoostState + +namespace GeneratedCommandList { +static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; +} // namespace GeneratedCommandList + +namespace AcceptedCommandList { +static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; +} // namespace AcceptedCommandList + +namespace EventList { +static constexpr AttributeId Id = Globals::Attributes::EventList::Id; +} // namespace EventList + +namespace AttributeList { +static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; +} // namespace AttributeList + +namespace FeatureMap { +static constexpr AttributeId Id = Globals::Attributes::FeatureMap::Id; +} // namespace FeatureMap + +namespace ClusterRevision { +static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace WaterHeaterManagement + namespace DemandResponseLoadControl { namespace Attributes { @@ -6699,7 +6753,7 @@ static constexpr AttributeId Id = 0x00000003; } // namespace InterfaceEnabled namespace ActiveDatasetTimestamp { -static constexpr AttributeId Id = 0x00000005; +static constexpr AttributeId Id = 0x00000004; } // namespace ActiveDatasetTimestamp namespace GeneratedCommandList { @@ -7359,6 +7413,40 @@ static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; } // namespace Attributes } // namespace ContentAppObserver +namespace CommissionerControl { +namespace Attributes { + +namespace SupportedDeviceCategories { +static constexpr AttributeId Id = 0x00000000; +} // namespace SupportedDeviceCategories + +namespace GeneratedCommandList { +static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; +} // namespace GeneratedCommandList + +namespace AcceptedCommandList { +static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; +} // namespace AcceptedCommandList + +namespace EventList { +static constexpr AttributeId Id = Globals::Attributes::EventList::Id; +} // namespace EventList + +namespace AttributeList { +static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; +} // namespace AttributeList + +namespace FeatureMap { +static constexpr AttributeId Id = Globals::Attributes::FeatureMap::Id; +} // namespace FeatureMap + +namespace ClusterRevision { +static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace CommissionerControl + namespace ElectricalMeasurement { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h index eab334c8ce3a29..ba42f10b50ffae 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h @@ -226,6 +226,9 @@ static constexpr ClusterId Id = 0x00000090; namespace ElectricalEnergyMeasurement { static constexpr ClusterId Id = 0x00000091; } // namespace ElectricalEnergyMeasurement +namespace WaterHeaterManagement { +static constexpr ClusterId Id = 0x00000094; +} // namespace WaterHeaterManagement namespace DemandResponseLoadControl { static constexpr ClusterId Id = 0x00000096; } // namespace DemandResponseLoadControl @@ -379,6 +382,9 @@ static constexpr ClusterId Id = 0x0000050F; namespace ContentAppObserver { static constexpr ClusterId Id = 0x00000510; } // namespace ContentAppObserver +namespace CommissionerControl { +static constexpr ClusterId Id = 0x00000751; +} // namespace CommissionerControl namespace ElectricalMeasurement { static constexpr ClusterId Id = 0x00000B04; } // namespace ElectricalMeasurement diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h index cff6ad343f0db3..608b7d7c7565a7 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h @@ -929,6 +929,20 @@ static constexpr CommandId Id = 0x00000001; } // namespace Commands } // namespace ValveConfigurationAndControl +namespace WaterHeaterManagement { +namespace Commands { + +namespace Boost { +static constexpr CommandId Id = 0x00000000; +} // namespace Boost + +namespace CancelBoost { +static constexpr CommandId Id = 0x00000001; +} // namespace CancelBoost + +} // namespace Commands +} // namespace WaterHeaterManagement + namespace DemandResponseLoadControl { namespace Commands { @@ -1429,15 +1443,15 @@ static constexpr CommandId Id = 0x00000001; } // namespace GetPendingDatasetRequest namespace DatasetResponse { -static constexpr CommandId Id = 0x00000003; +static constexpr CommandId Id = 0x00000002; } // namespace DatasetResponse namespace SetActiveDatasetRequest { -static constexpr CommandId Id = 0x00000004; +static constexpr CommandId Id = 0x00000003; } // namespace SetActiveDatasetRequest namespace SetPendingDatasetRequest { -static constexpr CommandId Id = 0x00000005; +static constexpr CommandId Id = 0x00000004; } // namespace SetPendingDatasetRequest } // namespace Commands @@ -1769,6 +1783,24 @@ static constexpr CommandId Id = 0x00000001; } // namespace Commands } // namespace ContentAppObserver +namespace CommissionerControl { +namespace Commands { + +namespace RequestCommissioningApproval { +static constexpr CommandId Id = 0x00000000; +} // namespace RequestCommissioningApproval + +namespace CommissionNode { +static constexpr CommandId Id = 0x00000001; +} // namespace CommissionNode + +namespace ReverseOpenCommissioningWindow { +static constexpr CommandId Id = 0x00000002; +} // namespace ReverseOpenCommissioningWindow + +} // namespace Commands +} // namespace CommissionerControl + namespace ElectricalMeasurement { namespace Commands { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Events.h b/zzz_generated/app-common/app-common/zap-generated/ids/Events.h index 1592020a008379..cc619b581dc3e6 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Events.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Events.h @@ -661,6 +661,16 @@ static constexpr EventId Id = 0x00000000; } // namespace Events } // namespace ContentControl +namespace CommissionerControl { +namespace Events { + +namespace CommissioningRequestResult { +static constexpr EventId Id = 0x00000000; +} // namespace CommissioningRequestResult + +} // namespace Events +} // namespace CommissionerControl + namespace UnitTesting { namespace Events { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index a7bae21539e5b8..63b07843fd2703 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -102,6 +102,7 @@ | ValveConfigurationAndControl | 0x0081 | | ElectricalPowerMeasurement | 0x0090 | | ElectricalEnergyMeasurement | 0x0091 | +| WaterHeaterManagement | 0x0094 | | DemandResponseLoadControl | 0x0096 | | Messages | 0x0097 | | DeviceEnergyManagement | 0x0098 | @@ -153,6 +154,7 @@ | AccountLogin | 0x050E | | ContentControl | 0x050F | | ContentAppObserver | 0x0510 | +| CommissionerControl | 0x0751 | | ElectricalMeasurement | 0x0B04 | | UnitTesting | 0xFFF1FC05| | FaultInjection | 0xFFF1FC06| @@ -6573,6 +6575,109 @@ class ValveConfigurationAndControlClose : public ClusterCommand | * PeriodicEnergyMeasured | 0x0001 | \*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*\ +| Cluster WaterHeaterManagement | 0x0094 | +|------------------------------------------------------------------------------| +| Commands: | | +| * Boost | 0x00 | +| * CancelBoost | 0x01 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * HeaterTypes | 0x0000 | +| * HeatDemand | 0x0001 | +| * TankVolume | 0x0002 | +| * EstimatedHeatRequired | 0x0003 | +| * TankPercentage | 0x0004 | +| * BoostState | 0x0005 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +/* + * Command Boost + */ +class WaterHeaterManagementBoost : public ClusterCommand +{ +public: + WaterHeaterManagementBoost(CredentialIssuerCommands * credsIssuerConfig) : ClusterCommand("boost", credsIssuerConfig) + { + AddArgument("Duration", 0, UINT32_MAX, &mRequest.duration); + AddArgument("OneShot", 0, 1, &mRequest.oneShot); + AddArgument("EmergencyBoost", 0, 1, &mRequest.emergencyBoost); + AddArgument("TemporarySetpoint", INT16_MIN, INT16_MAX, &mRequest.temporarySetpoint); + AddArgument("TargetPercentage", 0, UINT8_MAX, &mRequest.targetPercentage); + AddArgument("TargetReheat", 0, UINT8_MAX, &mRequest.targetReheat); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WaterHeaterManagement::Commands::Boost::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WaterHeaterManagement::Commands::Boost::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::WaterHeaterManagement::Commands::Boost::Type mRequest; +}; + +/* + * Command CancelBoost + */ +class WaterHeaterManagementCancelBoost : public ClusterCommand +{ +public: + WaterHeaterManagementCancelBoost(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("cancel-boost", credsIssuerConfig) + { + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WaterHeaterManagement::Commands::CancelBoost::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WaterHeaterManagement::Commands::CancelBoost::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::WaterHeaterManagement::Commands::CancelBoost::Type mRequest; +}; + /*----------------------------------------------------------------------------*\ | Cluster DemandResponseLoadControl | 0x0096 | |------------------------------------------------------------------------------| @@ -11185,15 +11290,15 @@ class WiFiNetworkManagementNetworkPassphraseRequest : public ClusterCommand | Commands: | | | * GetActiveDatasetRequest | 0x00 | | * GetPendingDatasetRequest | 0x01 | -| * SetActiveDatasetRequest | 0x04 | -| * SetPendingDatasetRequest | 0x05 | +| * SetActiveDatasetRequest | 0x03 | +| * SetPendingDatasetRequest | 0x04 | |------------------------------------------------------------------------------| | Attributes: | | | * BorderRouterName | 0x0000 | | * BorderAgentID | 0x0001 | | * ThreadVersion | 0x0002 | | * InterfaceEnabled | 0x0003 | -| * ActiveDatasetTimestamp | 0x0005 | +| * ActiveDatasetTimestamp | 0x0004 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -13651,6 +13756,108 @@ class ContentAppObserverContentAppMessage : public ClusterCommand chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessage::Type mRequest; }; +/*----------------------------------------------------------------------------*\ +| Cluster CommissionerControl | 0x0751 | +|------------------------------------------------------------------------------| +| Commands: | | +| * RequestCommissioningApproval | 0x00 | +| * CommissionNode | 0x01 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * SupportedDeviceCategories | 0x0000 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +| * CommissioningRequestResult | 0x0000 | +\*----------------------------------------------------------------------------*/ + +/* + * Command RequestCommissioningApproval + */ +class CommissionerControlRequestCommissioningApproval : public ClusterCommand +{ +public: + CommissionerControlRequestCommissioningApproval(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("request-commissioning-approval", credsIssuerConfig) + { + AddArgument("RequestId", 0, UINT64_MAX, &mRequest.requestId); + AddArgument("VendorId", 0, UINT16_MAX, &mRequest.vendorId); + AddArgument("ProductId", 0, UINT16_MAX, &mRequest.productId); + AddArgument("Label", &mRequest.label); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Type mRequest; +}; + +/* + * Command CommissionNode + */ +class CommissionerControlCommissionNode : public ClusterCommand +{ +public: + CommissionerControlCommissionNode(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("commission-node", credsIssuerConfig) + { + AddArgument("RequestId", 0, UINT64_MAX, &mRequest.requestId); + AddArgument("ResponseTimeoutSeconds", 0, UINT16_MAX, &mRequest.responseTimeoutSeconds); + AddArgument("IpAddress", &mRequest.ipAddress); + AddArgument("Port", 0, UINT16_MAX, &mRequest.port); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::CommissionerControl::Commands::CommissionNode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::CommissionerControl::Commands::CommissionNode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::CommissionerControl::Commands::CommissionNode::Type mRequest; +}; + /*----------------------------------------------------------------------------*\ | Cluster ElectricalMeasurement | 0x0B04 | |------------------------------------------------------------------------------| @@ -20903,6 +21110,84 @@ void registerClusterElectricalEnergyMeasurement(Commands & commands, CredentialI commands.RegisterCluster(clusterName, clusterCommands); } +void registerClusterWaterHeaterManagement(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) +{ + using namespace chip::app::Clusters::WaterHeaterManagement; + + const char * clusterName = "WaterHeaterManagement"; + + commands_list clusterCommands = { + // + // Commands + // + make_unique(Id, credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // + // + // Attributes + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "heater-types", Attributes::HeaterTypes::Id, credsIssuerConfig), // + make_unique(Id, "heat-demand", Attributes::HeatDemand::Id, credsIssuerConfig), // + make_unique(Id, "tank-volume", Attributes::TankVolume::Id, credsIssuerConfig), // + make_unique(Id, "estimated-heat-required", Attributes::EstimatedHeatRequired::Id, credsIssuerConfig), // + make_unique(Id, "tank-percentage", Attributes::TankPercentage::Id, credsIssuerConfig), // + make_unique(Id, "boost-state", Attributes::BoostState::Id, credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + make_unique>(Id, credsIssuerConfig), // + make_unique>>( + Id, "heater-types", 0, UINT8_MAX, Attributes::HeaterTypes::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "heat-demand", 0, UINT8_MAX, Attributes::HeatDemand::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "tank-volume", 0, UINT16_MAX, Attributes::TankVolume::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "estimated-heat-required", INT64_MIN, INT64_MAX, + Attributes::EstimatedHeatRequired::Id, WriteCommandType::kForceWrite, + credsIssuerConfig), // + make_unique>(Id, "tank-percentage", 0, UINT8_MAX, Attributes::TankPercentage::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>( + Id, "boost-state", 0, UINT8_MAX, Attributes::BoostState::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, + credsIssuerConfig), // + make_unique>>( + Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "cluster-revision", 0, UINT16_MAX, Attributes::ClusterRevision::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "heater-types", Attributes::HeaterTypes::Id, credsIssuerConfig), // + make_unique(Id, "heat-demand", Attributes::HeatDemand::Id, credsIssuerConfig), // + make_unique(Id, "tank-volume", Attributes::TankVolume::Id, credsIssuerConfig), // + make_unique(Id, "estimated-heat-required", Attributes::EstimatedHeatRequired::Id, credsIssuerConfig), // + make_unique(Id, "tank-percentage", Attributes::TankPercentage::Id, credsIssuerConfig), // + make_unique(Id, "boost-state", Attributes::BoostState::Id, credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + // + // Events + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + }; + + commands.RegisterCluster(clusterName, clusterCommands); +} void registerClusterDemandResponseLoadControl(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) { using namespace chip::app::Clusters::DemandResponseLoadControl; @@ -26289,6 +26574,69 @@ void registerClusterContentAppObserver(Commands & commands, CredentialIssuerComm commands.RegisterCluster(clusterName, clusterCommands); } +void registerClusterCommissionerControl(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) +{ + using namespace chip::app::Clusters::CommissionerControl; + + const char * clusterName = "CommissionerControl"; + + commands_list clusterCommands = { + // + // Commands + // + make_unique(Id, credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // + // + // Attributes + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "supported-device-categories", Attributes::SupportedDeviceCategories::Id, + credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + make_unique>(Id, credsIssuerConfig), // + make_unique>>( + Id, "supported-device-categories", 0, UINT32_MAX, Attributes::SupportedDeviceCategories::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, + credsIssuerConfig), // + make_unique>>( + Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "cluster-revision", 0, UINT16_MAX, Attributes::ClusterRevision::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "supported-device-categories", Attributes::SupportedDeviceCategories::Id, + credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + // + // Events + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "commissioning-request-result", Events::CommissioningRequestResult::Id, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "commissioning-request-result", Events::CommissioningRequestResult::Id, + credsIssuerConfig), // + }; + + commands.RegisterCluster(clusterName, clusterCommands); +} void registerClusterElectricalMeasurement(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) { using namespace chip::app::Clusters::ElectricalMeasurement; @@ -27646,6 +27994,7 @@ void registerClusters(Commands & commands, CredentialIssuerCommands * credsIssue registerClusterValveConfigurationAndControl(commands, credsIssuerConfig); registerClusterElectricalPowerMeasurement(commands, credsIssuerConfig); registerClusterElectricalEnergyMeasurement(commands, credsIssuerConfig); + registerClusterWaterHeaterManagement(commands, credsIssuerConfig); registerClusterDemandResponseLoadControl(commands, credsIssuerConfig); registerClusterMessages(commands, credsIssuerConfig); registerClusterDeviceEnergyManagement(commands, credsIssuerConfig); @@ -27697,6 +28046,7 @@ void registerClusters(Commands & commands, CredentialIssuerCommands * credsIssue registerClusterAccountLogin(commands, credsIssuerConfig); registerClusterContentControl(commands, credsIssuerConfig); registerClusterContentAppObserver(commands, credsIssuerConfig); + registerClusterCommissionerControl(commands, credsIssuerConfig); registerClusterElectricalMeasurement(commands, credsIssuerConfig); registerClusterUnitTesting(commands, credsIssuerConfig); registerClusterFaultInjection(commands, credsIssuerConfig); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index ec9b3c4b962c17..1bf30e655ab661 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -6850,6 +6850,14 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, return err; } } + { + CHIP_ERROR err = DataModelLogger::LogValue("MaximumDischargeCurrent", indent + 1, value.maximumDischargeCurrent); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'MaximumDischargeCurrent'"); + return err; + } + } DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; @@ -6890,6 +6898,14 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, return err; } } + { + CHIP_ERROR err = DataModelLogger::LogValue("EnergyDischarged", indent + 1, value.energyDischarged); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'EnergyDischarged'"); + return err; + } + } DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; @@ -7452,6 +7468,46 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, return CHIP_NO_ERROR; } +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const CommissionerControl::Events::CommissioningRequestResult::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = DataModelLogger::LogValue("RequestId", indent + 1, value.requestId); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'RequestId'"); + return err; + } + } + { + CHIP_ERROR err = DataModelLogger::LogValue("ClientNodeId", indent + 1, value.clientNodeId); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'ClientNodeId'"); + return err; + } + } + { + CHIP_ERROR err = DataModelLogger::LogValue("StatusCode", indent + 1, value.statusCode); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'StatusCode'"); + return err; + } + } + { + CHIP_ERROR err = DataModelLogger::LogValue("FabricIndex", indent + 1, value.fabricIndex); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'FabricIndex'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const UnitTesting::Events::TestEvent::DecodableType & value) { DataModelLogger::LogString(label, indent, "{"); @@ -8196,6 +8252,18 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; } +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("commissioningTimeout", indent + 1, value.commissioningTimeout)); + ReturnErrorOnFailure(DataModelLogger::LogValue("PAKEPasscodeVerifier", indent + 1, value.PAKEPasscodeVerifier)); + ReturnErrorOnFailure(DataModelLogger::LogValue("discriminator", indent + 1, value.discriminator)); + ReturnErrorOnFailure(DataModelLogger::LogValue("iterations", indent + 1, value.iterations)); + ReturnErrorOnFailure(DataModelLogger::LogValue("salt", indent + 1, value.salt)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const ElectricalMeasurement::Commands::GetProfileInfoResponseCommand::DecodableType & value) { @@ -13046,6 +13114,72 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP } break; } + case WaterHeaterManagement::Id: { + switch (path.mAttributeId) + { + case WaterHeaterManagement::Attributes::HeaterTypes::Id: { + chip::BitMask value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("HeaterTypes", 1, value); + } + case WaterHeaterManagement::Attributes::HeatDemand::Id: { + chip::BitMask value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("HeatDemand", 1, value); + } + case WaterHeaterManagement::Attributes::TankVolume::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("TankVolume", 1, value); + } + case WaterHeaterManagement::Attributes::EstimatedHeatRequired::Id: { + int64_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EstimatedHeatRequired", 1, value); + } + case WaterHeaterManagement::Attributes::TankPercentage::Id: { + chip::Percent value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("TankPercentage", 1, value); + } + case WaterHeaterManagement::Attributes::BoostState::Id: { + chip::app::Clusters::WaterHeaterManagement::BoostStateEnum value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("BoostState", 1, value); + } + case WaterHeaterManagement::Attributes::GeneratedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("GeneratedCommandList", 1, value); + } + case WaterHeaterManagement::Attributes::AcceptedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AcceptedCommandList", 1, value); + } + case WaterHeaterManagement::Attributes::EventList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EventList", 1, value); + } + case WaterHeaterManagement::Attributes::AttributeList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AttributeList", 1, value); + } + case WaterHeaterManagement::Attributes::FeatureMap::Id: { + uint32_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("FeatureMap", 1, value); + } + case WaterHeaterManagement::Attributes::ClusterRevision::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ClusterRevision", 1, value); + } + } + break; + } case DemandResponseLoadControl::Id: { switch (path.mAttributeId) { @@ -17444,6 +17578,47 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP } break; } + case CommissionerControl::Id: { + switch (path.mAttributeId) + { + case CommissionerControl::Attributes::SupportedDeviceCategories::Id: { + chip::BitMask value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("SupportedDeviceCategories", 1, value); + } + case CommissionerControl::Attributes::GeneratedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("GeneratedCommandList", 1, value); + } + case CommissionerControl::Attributes::AcceptedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AcceptedCommandList", 1, value); + } + case CommissionerControl::Attributes::EventList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EventList", 1, value); + } + case CommissionerControl::Attributes::AttributeList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AttributeList", 1, value); + } + case CommissionerControl::Attributes::FeatureMap::Id: { + uint32_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("FeatureMap", 1, value); + } + case CommissionerControl::Attributes::ClusterRevision::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ClusterRevision", 1, value); + } + } + break; + } case ElectricalMeasurement::Id: { switch (path.mAttributeId) { @@ -19223,6 +19398,17 @@ CHIP_ERROR DataModelLogger::LogCommand(const chip::app::ConcreteCommandPath & pa } break; } + case CommissionerControl::Id: { + switch (path.mCommandId) + { + case CommissionerControl::Commands::ReverseOpenCommissioningWindow::Id: { + CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ReverseOpenCommissioningWindow", 1, value); + } + } + break; + } case ElectricalMeasurement::Id: { switch (path.mCommandId) { @@ -20110,6 +20296,17 @@ CHIP_ERROR DataModelLogger::LogEvent(const chip::app::EventHeader & header, chip } break; } + case CommissionerControl::Id: { + switch (header.mPath.mEventId) + { + case CommissionerControl::Events::CommissioningRequestResult::Id: { + chip::app::Clusters::CommissionerControl::Events::CommissioningRequestResult::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("CommissioningRequestResult", 1, value); + } + } + break; + } case UnitTesting::Id: { switch (header.mPath.mEventId) { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h index 922ae495192512..7aecdf187d7a49 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h @@ -637,6 +637,9 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::AccountLogin::Events::LoggedOut::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::ContentControl::Events::RemainingScreenTimeExpired::DecodableType & value); +static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::CommissionerControl::Events::CommissioningRequestResult::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::UnitTesting::Events::TestEvent::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, @@ -797,6 +800,9 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessageResponse::DecodableType & value); static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::ElectricalMeasurement::Commands::GetProfileInfoResponseCommand::DecodableType & value); static CHIP_ERROR diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index 166c18b63911e4..9d6610f69f3faf 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -104,6 +104,7 @@ | ValveConfigurationAndControl | 0x0081 | | ElectricalPowerMeasurement | 0x0090 | | ElectricalEnergyMeasurement | 0x0091 | +| WaterHeaterManagement | 0x0094 | | DemandResponseLoadControl | 0x0096 | | Messages | 0x0097 | | DeviceEnergyManagement | 0x0098 | @@ -155,6 +156,7 @@ | AccountLogin | 0x050E | | ContentControl | 0x050F | | ContentAppObserver | 0x0510 | +| CommissionerControl | 0x0751 | | ElectricalMeasurement | 0x0B04 | | UnitTesting | 0xFFF1FC05| | FaultInjection | 0xFFF1FC06| @@ -78994,6 +78996,1202 @@ class SubscribeAttributeElectricalEnergyMeasurementClusterRevision : public Subs } }; +#if MTR_ENABLE_PROVISIONAL +/*----------------------------------------------------------------------------*\ +| Cluster WaterHeaterManagement | 0x0094 | +|------------------------------------------------------------------------------| +| Commands: | | +| * Boost | 0x00 | +| * CancelBoost | 0x01 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * HeaterTypes | 0x0000 | +| * HeatDemand | 0x0001 | +| * TankVolume | 0x0002 | +| * EstimatedHeatRequired | 0x0003 | +| * TankPercentage | 0x0004 | +| * BoostState | 0x0005 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +#if MTR_ENABLE_PROVISIONAL +/* + * Command Boost + */ +class WaterHeaterManagementBoost : public ClusterCommand { +public: + WaterHeaterManagementBoost() + : ClusterCommand("boost") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("Duration", 0, UINT32_MAX, &mRequest.duration); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("OneShot", 0, 1, &mRequest.oneShot); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("EmergencyBoost", 0, 1, &mRequest.emergencyBoost); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("TemporarySetpoint", INT16_MIN, INT16_MAX, &mRequest.temporarySetpoint); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("TargetPercentage", 0, UINT8_MAX, &mRequest.targetPercentage); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("TargetReheat", 0, UINT8_MAX, &mRequest.targetReheat); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WaterHeaterManagement::Commands::Boost::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWaterHeaterManagementClusterBoostParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.duration = [NSNumber numberWithUnsignedInt:mRequest.duration]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.oneShot.HasValue()) { + params.oneShot = [NSNumber numberWithBool:mRequest.oneShot.Value()]; + } else { + params.oneShot = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.emergencyBoost.HasValue()) { + params.emergencyBoost = [NSNumber numberWithBool:mRequest.emergencyBoost.Value()]; + } else { + params.emergencyBoost = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.temporarySetpoint.HasValue()) { + params.temporarySetpoint = [NSNumber numberWithShort:mRequest.temporarySetpoint.Value()]; + } else { + params.temporarySetpoint = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.targetPercentage.HasValue()) { + params.targetPercentage = [NSNumber numberWithUnsignedChar:mRequest.targetPercentage.Value()]; + } else { + params.targetPercentage = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.targetReheat.HasValue()) { + params.targetReheat = [NSNumber numberWithUnsignedChar:mRequest.targetReheat.Value()]; + } else { + params.targetReheat = nil; + } +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster boostWithParams:params completion: + ^(NSError * _Nullable error) { + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::WaterHeaterManagement::Commands::Boost::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command CancelBoost + */ +class WaterHeaterManagementCancelBoost : public ClusterCommand { +public: + WaterHeaterManagementCancelBoost() + : ClusterCommand("cancel-boost") + { + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WaterHeaterManagement::Commands::CancelBoost::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWaterHeaterManagementClusterCancelBoostParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster cancelBoostWithParams:params completion: + ^(NSError * _Nullable error) { + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: +}; + +#endif // MTR_ENABLE_PROVISIONAL + +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute HeaterTypes + */ +class ReadWaterHeaterManagementHeaterTypes : public ReadAttribute { +public: + ReadWaterHeaterManagementHeaterTypes() + : ReadAttribute("heater-types") + { + } + + ~ReadWaterHeaterManagementHeaterTypes() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::HeaterTypes::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeHeaterTypesWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.HeaterTypes response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterManagement HeaterTypes read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterManagementHeaterTypes : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterManagementHeaterTypes() + : SubscribeAttribute("heater-types") + { + } + + ~SubscribeAttributeWaterHeaterManagementHeaterTypes() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::HeaterTypes::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeHeaterTypesWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.HeaterTypes response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute HeatDemand + */ +class ReadWaterHeaterManagementHeatDemand : public ReadAttribute { +public: + ReadWaterHeaterManagementHeatDemand() + : ReadAttribute("heat-demand") + { + } + + ~ReadWaterHeaterManagementHeatDemand() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::HeatDemand::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeHeatDemandWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.HeatDemand response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterManagement HeatDemand read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterManagementHeatDemand : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterManagementHeatDemand() + : SubscribeAttribute("heat-demand") + { + } + + ~SubscribeAttributeWaterHeaterManagementHeatDemand() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::HeatDemand::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeHeatDemandWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.HeatDemand response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute TankVolume + */ +class ReadWaterHeaterManagementTankVolume : public ReadAttribute { +public: + ReadWaterHeaterManagementTankVolume() + : ReadAttribute("tank-volume") + { + } + + ~ReadWaterHeaterManagementTankVolume() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::TankVolume::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeTankVolumeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.TankVolume response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterManagement TankVolume read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterManagementTankVolume : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterManagementTankVolume() + : SubscribeAttribute("tank-volume") + { + } + + ~SubscribeAttributeWaterHeaterManagementTankVolume() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::TankVolume::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeTankVolumeWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.TankVolume response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute EstimatedHeatRequired + */ +class ReadWaterHeaterManagementEstimatedHeatRequired : public ReadAttribute { +public: + ReadWaterHeaterManagementEstimatedHeatRequired() + : ReadAttribute("estimated-heat-required") + { + } + + ~ReadWaterHeaterManagementEstimatedHeatRequired() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::EstimatedHeatRequired::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEstimatedHeatRequiredWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.EstimatedHeatRequired response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterManagement EstimatedHeatRequired read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterManagementEstimatedHeatRequired : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterManagementEstimatedHeatRequired() + : SubscribeAttribute("estimated-heat-required") + { + } + + ~SubscribeAttributeWaterHeaterManagementEstimatedHeatRequired() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::EstimatedHeatRequired::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeEstimatedHeatRequiredWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.EstimatedHeatRequired response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute TankPercentage + */ +class ReadWaterHeaterManagementTankPercentage : public ReadAttribute { +public: + ReadWaterHeaterManagementTankPercentage() + : ReadAttribute("tank-percentage") + { + } + + ~ReadWaterHeaterManagementTankPercentage() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::TankPercentage::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeTankPercentageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.TankPercentage response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterManagement TankPercentage read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterManagementTankPercentage : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterManagementTankPercentage() + : SubscribeAttribute("tank-percentage") + { + } + + ~SubscribeAttributeWaterHeaterManagementTankPercentage() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::TankPercentage::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeTankPercentageWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.TankPercentage response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute BoostState + */ +class ReadWaterHeaterManagementBoostState : public ReadAttribute { +public: + ReadWaterHeaterManagementBoostState() + : ReadAttribute("boost-state") + { + } + + ~ReadWaterHeaterManagementBoostState() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::BoostState::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeBoostStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.BoostState response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterManagement BoostState read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterManagementBoostState : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterManagementBoostState() + : SubscribeAttribute("boost-state") + { + } + + ~SubscribeAttributeWaterHeaterManagementBoostState() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::BoostState::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeBoostStateWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.BoostState response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute GeneratedCommandList + */ +class ReadWaterHeaterManagementGeneratedCommandList : public ReadAttribute { +public: + ReadWaterHeaterManagementGeneratedCommandList() + : ReadAttribute("generated-command-list") + { + } + + ~ReadWaterHeaterManagementGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterManagement GeneratedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterManagementGeneratedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterManagementGeneratedCommandList() + : SubscribeAttribute("generated-command-list") + { + } + + ~SubscribeAttributeWaterHeaterManagementGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeGeneratedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AcceptedCommandList + */ +class ReadWaterHeaterManagementAcceptedCommandList : public ReadAttribute { +public: + ReadWaterHeaterManagementAcceptedCommandList() + : ReadAttribute("accepted-command-list") + { + } + + ~ReadWaterHeaterManagementAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterManagement AcceptedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterManagementAcceptedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterManagementAcceptedCommandList() + : SubscribeAttribute("accepted-command-list") + { + } + + ~SubscribeAttributeWaterHeaterManagementAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAcceptedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute EventList + */ +class ReadWaterHeaterManagementEventList : public ReadAttribute { +public: + ReadWaterHeaterManagementEventList() + : ReadAttribute("event-list") + { + } + + ~ReadWaterHeaterManagementEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterManagement EventList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterManagementEventList : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterManagementEventList() + : SubscribeAttribute("event-list") + { + } + + ~SubscribeAttributeWaterHeaterManagementEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeEventListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AttributeList + */ +class ReadWaterHeaterManagementAttributeList : public ReadAttribute { +public: + ReadWaterHeaterManagementAttributeList() + : ReadAttribute("attribute-list") + { + } + + ~ReadWaterHeaterManagementAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterManagement AttributeList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterManagementAttributeList : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterManagementAttributeList() + : SubscribeAttribute("attribute-list") + { + } + + ~SubscribeAttributeWaterHeaterManagementAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAttributeListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute FeatureMap + */ +class ReadWaterHeaterManagementFeatureMap : public ReadAttribute { +public: + ReadWaterHeaterManagementFeatureMap() + : ReadAttribute("feature-map") + { + } + + ~ReadWaterHeaterManagementFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterManagement FeatureMap read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterManagementFeatureMap : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterManagementFeatureMap() + : SubscribeAttribute("feature-map") + { + } + + ~SubscribeAttributeWaterHeaterManagementFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeFeatureMapWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ClusterRevision + */ +class ReadWaterHeaterManagementClusterRevision : public ReadAttribute { +public: + ReadWaterHeaterManagementClusterRevision() + : ReadAttribute("cluster-revision") + { + } + + ~ReadWaterHeaterManagementClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterManagement ClusterRevision read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterManagementClusterRevision : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterManagementClusterRevision() + : SubscribeAttribute("cluster-revision") + { + } + + ~SubscribeAttributeWaterHeaterManagementClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeClusterRevisionWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterManagement.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL /*----------------------------------------------------------------------------*\ | Cluster DemandResponseLoadControl | 0x0096 | @@ -145154,15 +146352,15 @@ class SubscribeAttributeWiFiNetworkManagementClusterRevision : public SubscribeA | Commands: | | | * GetActiveDatasetRequest | 0x00 | | * GetPendingDatasetRequest | 0x01 | -| * SetActiveDatasetRequest | 0x04 | -| * SetPendingDatasetRequest | 0x05 | +| * SetActiveDatasetRequest | 0x03 | +| * SetPendingDatasetRequest | 0x04 | |------------------------------------------------------------------------------| | Attributes: | | | * BorderRouterName | 0x0000 | | * BorderAgentID | 0x0001 | | * ThreadVersion | 0x0002 | | * InterfaceEnabled | 0x0003 | -| * ActiveDatasetTimestamp | 0x0005 | +| * ActiveDatasetTimestamp | 0x0004 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -161079,6 +162277,784 @@ class SubscribeAttributeContentAppObserverClusterRevision : public SubscribeAttr } }; +#endif // MTR_ENABLE_PROVISIONAL +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/*----------------------------------------------------------------------------*\ +| Cluster CommissionerControl | 0x0751 | +|------------------------------------------------------------------------------| +| Commands: | | +| * RequestCommissioningApproval | 0x00 | +| * CommissionNode | 0x01 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * SupportedDeviceCategories | 0x0000 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +| * CommissioningRequestResult | 0x0000 | +\*----------------------------------------------------------------------------*/ + +#if MTR_ENABLE_PROVISIONAL +/* + * Command RequestCommissioningApproval + */ +class CommissionerControlRequestCommissioningApproval : public ClusterCommand { +public: + CommissionerControlRequestCommissioningApproval() + : ClusterCommand("request-commissioning-approval") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("RequestId", 0, UINT64_MAX, &mRequest.requestId); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("VendorId", 0, UINT16_MAX, &mRequest.vendorId); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("ProductId", 0, UINT16_MAX, &mRequest.productId); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("Label", &mRequest.label); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRCommissionerControlClusterRequestCommissioningApprovalParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.requestId = [NSNumber numberWithUnsignedLongLong:mRequest.requestId]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.vendorId = [NSNumber numberWithUnsignedShort:chip::to_underlying(mRequest.vendorId)]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.productId = [NSNumber numberWithUnsignedShort:mRequest.productId]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.label.HasValue()) { + params.label = [[NSString alloc] initWithBytes:mRequest.label.Value().data() length:mRequest.label.Value().size() encoding:NSUTF8StringEncoding]; + } else { + params.label = nil; + } +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster requestCommissioningApprovalWithParams:params completion: + ^(NSError * _Nullable error) { + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command CommissionNode + */ +class CommissionerControlCommissionNode : public ClusterCommand { +public: + CommissionerControlCommissionNode() + : ClusterCommand("commission-node") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("RequestId", 0, UINT64_MAX, &mRequest.requestId); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("ResponseTimeoutSeconds", 0, UINT16_MAX, &mRequest.responseTimeoutSeconds); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("IpAddress", &mRequest.ipAddress); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("Port", 0, UINT16_MAX, &mRequest.port); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::CommissionerControl::Commands::CommissionNode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRCommissionerControlClusterCommissionNodeParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.requestId = [NSNumber numberWithUnsignedLongLong:mRequest.requestId]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.responseTimeoutSeconds = [NSNumber numberWithUnsignedShort:mRequest.responseTimeoutSeconds]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.ipAddress.HasValue()) { + params.ipAddress = [NSData dataWithBytes:mRequest.ipAddress.Value().data() length:mRequest.ipAddress.Value().size()]; + } else { + params.ipAddress = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.port.HasValue()) { + params.port = [NSNumber numberWithUnsignedShort:mRequest.port.Value()]; + } else { + params.port = nil; + } +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster commissionNodeWithParams:params completion: + ^(MTRCommissionerControlClusterReverseOpenCommissioningWindowParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::CommissionerControl::Commands::CommissionNode::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL + +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute SupportedDeviceCategories + */ +class ReadCommissionerControlSupportedDeviceCategories : public ReadAttribute { +public: + ReadCommissionerControlSupportedDeviceCategories() + : ReadAttribute("supported-device-categories") + { + } + + ~ReadCommissionerControlSupportedDeviceCategories() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::CommissionerControl::Attributes::SupportedDeviceCategories::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeSupportedDeviceCategoriesWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.SupportedDeviceCategories response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("CommissionerControl SupportedDeviceCategories read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeCommissionerControlSupportedDeviceCategories : public SubscribeAttribute { +public: + SubscribeAttributeCommissionerControlSupportedDeviceCategories() + : SubscribeAttribute("supported-device-categories") + { + } + + ~SubscribeAttributeCommissionerControlSupportedDeviceCategories() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::CommissionerControl::Attributes::SupportedDeviceCategories::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeSupportedDeviceCategoriesWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.SupportedDeviceCategories response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute GeneratedCommandList + */ +class ReadCommissionerControlGeneratedCommandList : public ReadAttribute { +public: + ReadCommissionerControlGeneratedCommandList() + : ReadAttribute("generated-command-list") + { + } + + ~ReadCommissionerControlGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::CommissionerControl::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("CommissionerControl GeneratedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeCommissionerControlGeneratedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeCommissionerControlGeneratedCommandList() + : SubscribeAttribute("generated-command-list") + { + } + + ~SubscribeAttributeCommissionerControlGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::CommissionerControl::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeGeneratedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AcceptedCommandList + */ +class ReadCommissionerControlAcceptedCommandList : public ReadAttribute { +public: + ReadCommissionerControlAcceptedCommandList() + : ReadAttribute("accepted-command-list") + { + } + + ~ReadCommissionerControlAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::CommissionerControl::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("CommissionerControl AcceptedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeCommissionerControlAcceptedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeCommissionerControlAcceptedCommandList() + : SubscribeAttribute("accepted-command-list") + { + } + + ~SubscribeAttributeCommissionerControlAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::CommissionerControl::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAcceptedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute EventList + */ +class ReadCommissionerControlEventList : public ReadAttribute { +public: + ReadCommissionerControlEventList() + : ReadAttribute("event-list") + { + } + + ~ReadCommissionerControlEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::CommissionerControl::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("CommissionerControl EventList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeCommissionerControlEventList : public SubscribeAttribute { +public: + SubscribeAttributeCommissionerControlEventList() + : SubscribeAttribute("event-list") + { + } + + ~SubscribeAttributeCommissionerControlEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::CommissionerControl::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeEventListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AttributeList + */ +class ReadCommissionerControlAttributeList : public ReadAttribute { +public: + ReadCommissionerControlAttributeList() + : ReadAttribute("attribute-list") + { + } + + ~ReadCommissionerControlAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::CommissionerControl::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("CommissionerControl AttributeList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeCommissionerControlAttributeList : public SubscribeAttribute { +public: + SubscribeAttributeCommissionerControlAttributeList() + : SubscribeAttribute("attribute-list") + { + } + + ~SubscribeAttributeCommissionerControlAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::CommissionerControl::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAttributeListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute FeatureMap + */ +class ReadCommissionerControlFeatureMap : public ReadAttribute { +public: + ReadCommissionerControlFeatureMap() + : ReadAttribute("feature-map") + { + } + + ~ReadCommissionerControlFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::CommissionerControl::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("CommissionerControl FeatureMap read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeCommissionerControlFeatureMap : public SubscribeAttribute { +public: + SubscribeAttributeCommissionerControlFeatureMap() + : SubscribeAttribute("feature-map") + { + } + + ~SubscribeAttributeCommissionerControlFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::CommissionerControl::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeFeatureMapWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ClusterRevision + */ +class ReadCommissionerControlClusterRevision : public ReadAttribute { +public: + ReadCommissionerControlClusterRevision() + : ReadAttribute("cluster-revision") + { + } + + ~ReadCommissionerControlClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::CommissionerControl::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("CommissionerControl ClusterRevision read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeCommissionerControlClusterRevision : public SubscribeAttribute { +public: + SubscribeAttributeCommissionerControlClusterRevision() + : SubscribeAttribute("cluster-revision") + { + } + + ~SubscribeAttributeCommissionerControlClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::CommissionerControl::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeClusterRevisionWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + #endif // MTR_ENABLE_PROVISIONAL #endif // MTR_ENABLE_PROVISIONAL /*----------------------------------------------------------------------------*\ @@ -189859,6 +191835,77 @@ void registerClusterElectricalEnergyMeasurement(Commands & commands) commands.RegisterCluster(clusterName, clusterCommands); } +void registerClusterWaterHeaterManagement(Commands & commands) +{ +#if MTR_ENABLE_PROVISIONAL + using namespace chip::app::Clusters::WaterHeaterManagement; + + const char * clusterName = "WaterHeaterManagement"; + + commands_list clusterCommands = { + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + make_unique(Id), // + make_unique(Id), // + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + }; + + commands.RegisterCluster(clusterName, clusterCommands); +#endif // MTR_ENABLE_PROVISIONAL +} void registerClusterDemandResponseLoadControl(Commands & commands) { #if MTR_ENABLE_PROVISIONAL @@ -193137,6 +195184,59 @@ void registerClusterContentAppObserver(Commands & commands) commands.RegisterCluster(clusterName, clusterCommands); #endif // MTR_ENABLE_PROVISIONAL } +void registerClusterCommissionerControl(Commands & commands) +{ +#if MTR_ENABLE_PROVISIONAL + using namespace chip::app::Clusters::CommissionerControl; + + const char * clusterName = "CommissionerControl"; + + commands_list clusterCommands = { + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + make_unique(Id), // + make_unique(Id), // + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + make_unique(Id), // + make_unique(Id), // + }; + + commands.RegisterCluster(clusterName, clusterCommands); +#endif // MTR_ENABLE_PROVISIONAL +} void registerClusterElectricalMeasurement(Commands & commands) { using namespace chip::app::Clusters::ElectricalMeasurement; @@ -193887,6 +195987,7 @@ void registerClusters(Commands & commands) registerClusterValveConfigurationAndControl(commands); registerClusterElectricalPowerMeasurement(commands); registerClusterElectricalEnergyMeasurement(commands); + registerClusterWaterHeaterManagement(commands); registerClusterDemandResponseLoadControl(commands); registerClusterMessages(commands); registerClusterDeviceEnergyManagement(commands); @@ -193938,6 +196039,7 @@ void registerClusters(Commands & commands) registerClusterAccountLogin(commands); registerClusterContentControl(commands); registerClusterContentAppObserver(commands); + registerClusterCommissionerControl(commands); registerClusterElectricalMeasurement(commands); registerClusterUnitTesting(commands); registerClusterSampleMei(commands);