diff --git a/.github/actions/bootstrap-cache/action.yaml b/.github/actions/bootstrap-cache/action.yaml index 9a883ecf22da79..f5ed24ba3f06e7 100644 --- a/.github/actions/bootstrap-cache/action.yaml +++ b/.github/actions/bootstrap-cache/action.yaml @@ -11,7 +11,7 @@ runs: attempt_limit: 3 attempt_delay: 2000 with: | - key: ${{ runner.os }}-env-${{ hashFiles('scripts/setup/*', 'third_party/pigweed/**') }} + key: ${{ runner.os }}-env-${{ hashFiles('scripts/setup/*', 'third_party/pigweed/**', '/etc/lsb-release') }} path: | .environment build_overrides/pigweed_environment.gni diff --git a/.github/workflows/bloat_check.yaml b/.github/workflows/bloat_check.yaml index a28be330220581..d9a2a506724188 100644 --- a/.github/workflows/bloat_check.yaml +++ b/.github/workflows/bloat_check.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:64 + image: ghcr.io/project-chip/chip-build:65 steps: - name: Checkout diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index ab5e30d2abd1d4..c4215c5745d4fd 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) @@ -42,7 +42,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:64 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" @@ -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 @@ -456,7 +456,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:64 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/chef.yaml b/.github/workflows/chef.yaml index 0b330d86910a62..1af112cf6dc23a 100644 --- a/.github/workflows/chef.yaml +++ b/.github/workflows/chef.yaml @@ -35,7 +35,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:64 + image: ghcr.io/project-chip/chip-build:65 options: --user root steps: diff --git a/.github/workflows/examples-linux-standalone.yaml b/.github/workflows/examples-linux-standalone.yaml index 1fae7081caba6b..0307eedc057bfd 100644 --- a/.github/workflows/examples-linux-standalone.yaml +++ b/.github/workflows/examples-linux-standalone.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:64 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-linux-tv-casting-app.yaml b/.github/workflows/examples-linux-tv-casting-app.yaml index 235aa2cbebabd0..744c40b2654421 100644 --- a/.github/workflows/examples-linux-tv-casting-app.yaml +++ b/.github/workflows/examples-linux-tv-casting-app.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:64 + image: ghcr.io/project-chip/chip-build:65 steps: - name: Checkout diff --git a/.github/workflows/examples-mw320.yaml b/.github/workflows/examples-mw320.yaml index 759c0dc9582066..4b07c513db5d24 100644 --- a/.github/workflows/examples-mw320.yaml +++ b/.github/workflows/examples-mw320.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:64 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-nxp.yaml b/.github/workflows/examples-nxp.yaml index 130092cb258656..a4cb2101872cf8 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,24 +75,51 @@ 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 if: ${{ !env.ACT }} with: platform-name: K32W + + zephyr: + name: ZEPHYR_RW61X + + runs-on: ubuntu-latest + if: github.actor != 'restyled-io[bot]' + + container: + image: ghcr.io/project-chip/chip-build-nxp-zephyr:64 + + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Checkout submodules & Bootstrap + uses: ./.github/actions/checkout-submodules-and-bootstrap + with: + platform: nxp + + - name: Build RW61x Zephyr examples + run: | + scripts/run_in_build_env.sh "\ + ./scripts/build/build_examples.py \ + --target nxp-rw61x-zephyr-all-clusters \ + --target nxp-rw61x-zephyr-thermostat \ + --target nxp-rw61x-zephyr-laundry-washer-factory \ + build \ + " diff --git a/.github/workflows/examples-qpg.yaml b/.github/workflows/examples-qpg.yaml index 11c9cc1f013803..e015d3db3f5d08 100644 --- a/.github/workflows/examples-qpg.yaml +++ b/.github/workflows/examples-qpg.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:64 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-stm32.yaml b/.github/workflows/examples-stm32.yaml index ab113a8780dcbe..47435add440808 100644 --- a/.github/workflows/examples-stm32.yaml +++ b/.github/workflows/examples-stm32.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:64 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/fuzzing-build.yaml b/.github/workflows/fuzzing-build.yaml index 8dcabb223cbb78..17be73a9346d39 100644 --- a/.github/workflows/fuzzing-build.yaml +++ b/.github/workflows/fuzzing-build.yaml @@ -33,7 +33,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:64 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 66b745fb064d07..19cf8e8bd910b0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -35,7 +35,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:64 + image: ghcr.io/project-chip/chip-build:65 steps: - name: Checkout diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index dcb3adb599b9ba..cb8f5c6b6ed636 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 \ @@ -443,7 +445,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:64 + image: ghcr.io/project-chip/chip-build:65 options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=0 net.ipv6.conf.all.forwarding=0" @@ -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,8 @@ 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/TestConformanceSupport.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/.github/workflows/unit_integration_test.yaml b/.github/workflows/unit_integration_test.yaml index 4164020743c3f1..59e2dafc30cd63 100644 --- a/.github/workflows/unit_integration_test.yaml +++ b/.github/workflows/unit_integration_test.yaml @@ -39,7 +39,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:64 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/zap_regeneration.yaml b/.github/workflows/zap_regeneration.yaml index 0f134668d49ec2..356c8922b9419e 100644 --- a/.github/workflows/zap_regeneration.yaml +++ b/.github/workflows/zap_regeneration.yaml @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: ghcr.io/project-chip/chip-build:64 + image: ghcr.io/project-chip/chip-build:65 defaults: run: shell: sh diff --git a/.github/workflows/zap_templates.yaml b/.github/workflows/zap_templates.yaml index b7a9020259fa8a..2e9d5e82f1df90 100644 --- a/.github/workflows/zap_templates.yaml +++ b/.github/workflows/zap_templates.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: ghcr.io/project-chip/chip-build:64 + image: ghcr.io/project-chip/chip-build:65 defaults: run: shell: sh diff --git a/.vscode/settings.json b/.vscode/settings.json index d38758524ac8a5..397e6230087325 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -133,7 +133,8 @@ "random": "cpp", "thread": "cpp", "variant": "cpp", - "any": "cpp" + "any": "cpp", + "future": "cpp" }, // Configure paths or glob patterns to exclude from file watching. "files.watcherExclude": { 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/data_model/1.3/clusters/ACL-Cluster.xml b/data_model/1.3/clusters/ACL-Cluster.xml index a193ef2ac3206f..deed8c409337a5 100644 --- a/data_model/1.3/clusters/ACL-Cluster.xml +++ b/data_model/1.3/clusters/ACL-Cluster.xml @@ -169,19 +169,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/1.3/clusters/AdminCommissioningCluster.xml b/data_model/1.3/clusters/AdminCommissioningCluster.xml index ccbb579134dc00..8e95e46f128db0 100644 --- a/data_model/1.3/clusters/AdminCommissioningCluster.xml +++ b/data_model/1.3/clusters/AdminCommissioningCluster.xml @@ -91,12 +91,12 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/AlarmBase.xml b/data_model/1.3/clusters/AlarmBase.xml index fd0ccb5bc19d46..e374dcc382d208 100644 --- a/data_model/1.3/clusters/AlarmBase.xml +++ b/data_model/1.3/clusters/AlarmBase.xml @@ -80,7 +80,7 @@ Davis, CA 95616, USA - + @@ -91,7 +91,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ApplicationBasic.xml b/data_model/1.3/clusters/ApplicationBasic.xml index ee39b8a421209d..28e47e7800352e 100644 --- a/data_model/1.3/clusters/ApplicationBasic.xml +++ b/data_model/1.3/clusters/ApplicationBasic.xml @@ -92,29 +92,29 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -125,14 +125,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/ApplicationLauncher.xml b/data_model/1.3/clusters/ApplicationLauncher.xml index 57d6858dd8ce14..27fa528a81e8cf 100644 --- a/data_model/1.3/clusters/ApplicationLauncher.xml +++ b/data_model/1.3/clusters/ApplicationLauncher.xml @@ -103,14 +103,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/BallastConfiguration.xml b/data_model/1.3/clusters/BallastConfiguration.xml index 0f37d86067e994..9dbf4e61887d76 100644 --- a/data_model/1.3/clusters/BallastConfiguration.xml +++ b/data_model/1.3/clusters/BallastConfiguration.xml @@ -65,7 +65,9 @@ Davis, CA 95616, USA - + + + @@ -116,12 +118,12 @@ Davis, CA 95616, USA - + - + @@ -141,12 +143,12 @@ Davis, CA 95616, USA - + - + @@ -155,7 +157,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/BasicInformationCluster.xml b/data_model/1.3/clusters/BasicInformationCluster.xml index 137e8b70408bf8..69a882a09490d8 100644 --- a/data_model/1.3/clusters/BasicInformationCluster.xml +++ b/data_model/1.3/clusters/BasicInformationCluster.xml @@ -174,100 +174,100 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -276,29 +276,29 @@ Davis, CA 95616, USA - + - + - + - + - + diff --git a/data_model/1.3/clusters/Binding-Cluster.xml b/data_model/1.3/clusters/Binding-Cluster.xml index 444c99b315348d..055725f0b9ee47 100644 --- a/data_model/1.3/clusters/Binding-Cluster.xml +++ b/data_model/1.3/clusters/Binding-Cluster.xml @@ -97,7 +97,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/BooleanState.xml b/data_model/1.3/clusters/BooleanState.xml index 5bb29f53ae0c3e..ddb16e26a1d6ad 100644 --- a/data_model/1.3/clusters/BooleanState.xml +++ b/data_model/1.3/clusters/BooleanState.xml @@ -68,7 +68,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/BooleanStateConfiguration.xml b/data_model/1.3/clusters/BooleanStateConfiguration.xml index 01444d565294b3..719cd9569b5ae2 100644 --- a/data_model/1.3/clusters/BooleanStateConfiguration.xml +++ b/data_model/1.3/clusters/BooleanStateConfiguration.xml @@ -106,7 +106,7 @@ Davis, CA 95616, USA - + @@ -114,7 +114,7 @@ Davis, CA 95616, USA - + @@ -122,7 +122,7 @@ Davis, CA 95616, USA - + @@ -145,7 +145,7 @@ Davis, CA 95616, USA - + @@ -155,7 +155,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/Channel.xml b/data_model/1.3/clusters/Channel.xml index 17144c9032c3e5..6177bfe6a652cc 100644 --- a/data_model/1.3/clusters/Channel.xml +++ b/data_model/1.3/clusters/Channel.xml @@ -307,7 +307,7 @@ Davis, CA 95616, USA - + @@ -315,7 +315,7 @@ Davis, CA 95616, USA - + @@ -366,6 +366,7 @@ Davis, CA 95616, USA + @@ -400,6 +401,7 @@ Davis, CA 95616, USA + @@ -412,6 +414,7 @@ Davis, CA 95616, USA + @@ -437,6 +440,7 @@ Davis, CA 95616, USA + diff --git a/data_model/1.3/clusters/ColorControl.xml b/data_model/1.3/clusters/ColorControl.xml index 456b3ff14cfff9..ebf29e0b51e758 100644 --- a/data_model/1.3/clusters/ColorControl.xml +++ b/data_model/1.3/clusters/ColorControl.xml @@ -74,16 +74,16 @@ Davis, CA 95616, USA - + - + - + @@ -91,7 +91,7 @@ Davis, CA 95616, USA - + @@ -99,7 +99,7 @@ Davis, CA 95616, USA - + @@ -112,7 +112,7 @@ Davis, CA 95616, USA - + @@ -120,7 +120,7 @@ Davis, CA 95616, USA - + @@ -155,7 +155,7 @@ Davis, CA 95616, USA - + @@ -174,7 +174,7 @@ Davis, CA 95616, USA - + @@ -191,110 +191,110 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -319,7 +319,7 @@ Davis, CA 95616, USA - + @@ -334,7 +334,7 @@ Davis, CA 95616, USA - + @@ -349,12 +349,12 @@ Davis, CA 95616, USA - + - + @@ -375,27 +375,27 @@ Davis, CA 95616, USA - + - + - + - + @@ -439,11 +439,11 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/ConcentrationMeasurement.xml b/data_model/1.3/clusters/ConcentrationMeasurement.xml index 4b51cffa124321..b622a3560b4ff0 100644 --- a/data_model/1.3/clusters/ConcentrationMeasurement.xml +++ b/data_model/1.3/clusters/ConcentrationMeasurement.xml @@ -62,16 +62,16 @@ Davis, CA 95616, USA - - - - - - - - - - + + + + + + + + + + @@ -181,7 +181,7 @@ Davis, CA 95616, USA - + @@ -189,7 +189,7 @@ Davis, CA 95616, USA - + @@ -197,7 +197,7 @@ Davis, CA 95616, USA - + @@ -205,7 +205,7 @@ Davis, CA 95616, USA - + @@ -213,7 +213,7 @@ Davis, CA 95616, USA - + @@ -221,7 +221,7 @@ Davis, CA 95616, USA - + @@ -229,7 +229,7 @@ Davis, CA 95616, USA - + @@ -244,14 +244,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/ContentControl.xml b/data_model/1.3/clusters/ContentControl.xml index b2539cf445c289..6848886c43ac02 100644 --- a/data_model/1.3/clusters/ContentControl.xml +++ b/data_model/1.3/clusters/ContentControl.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/1.3/clusters/ContentLauncher.xml b/data_model/1.3/clusters/ContentLauncher.xml index 9a5674efa8eb64..b4d6e7fa26500c 100644 --- a/data_model/1.3/clusters/ContentLauncher.xml +++ b/data_model/1.3/clusters/ContentLauncher.xml @@ -299,7 +299,7 @@ Davis, CA 95616, USA - + @@ -307,7 +307,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/Descriptor-Cluster.xml b/data_model/1.3/clusters/Descriptor-Cluster.xml index 659b2ffaa5ddc0..d648f1c7f1be91 100644 --- a/data_model/1.3/clusters/Descriptor-Cluster.xml +++ b/data_model/1.3/clusters/Descriptor-Cluster.xml @@ -84,20 +84,20 @@ Davis, CA 95616, USA - + - + - + @@ -108,7 +108,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/DeviceEnergyManagement.xml b/data_model/1.3/clusters/DeviceEnergyManagement.xml index f74d7e572550cc..0fe30cc92e5506 100644 --- a/data_model/1.3/clusters/DeviceEnergyManagement.xml +++ b/data_model/1.3/clusters/DeviceEnergyManagement.xml @@ -64,7 +64,9 @@ Davis, CA 95616, USA - + + + @@ -473,6 +475,63 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/1.3/clusters/DiagnosticsEthernet.xml b/data_model/1.3/clusters/DiagnosticsEthernet.xml index dfcd3d11c41f52..fd2bb0341ca06c 100644 --- a/data_model/1.3/clusters/DiagnosticsEthernet.xml +++ b/data_model/1.3/clusters/DiagnosticsEthernet.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + @@ -108,57 +110,57 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + diff --git a/data_model/1.3/clusters/DiagnosticsGeneral.xml b/data_model/1.3/clusters/DiagnosticsGeneral.xml index 4da912b03dc3df..ff78100fe3a7d3 100644 --- a/data_model/1.3/clusters/DiagnosticsGeneral.xml +++ b/data_model/1.3/clusters/DiagnosticsGeneral.xml @@ -223,17 +223,17 @@ Davis, CA 95616, USA - + - + - + @@ -310,7 +310,6 @@ Davis, CA 95616, USA - diff --git a/data_model/1.3/clusters/DiagnosticsSoftware.xml b/data_model/1.3/clusters/DiagnosticsSoftware.xml index 7cb3c9ff39ad2f..c7ee8ee842bf02 100644 --- a/data_model/1.3/clusters/DiagnosticsSoftware.xml +++ b/data_model/1.3/clusters/DiagnosticsSoftware.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/1.3/clusters/DiagnosticsThread.xml b/data_model/1.3/clusters/DiagnosticsThread.xml index 120efaddf8c08e..1da3eba21a4e4e 100644 --- a/data_model/1.3/clusters/DiagnosticsThread.xml +++ b/data_model/1.3/clusters/DiagnosticsThread.xml @@ -63,7 +63,9 @@ Davis, CA 95616, USA - + + + @@ -257,38 +259,38 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + @@ -305,356 +307,356 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/data_model/1.3/clusters/DiagnosticsWiFi.xml b/data_model/1.3/clusters/DiagnosticsWiFi.xml index b3951d967dc31f..6ef28ee4cc09e0 100644 --- a/data_model/1.3/clusters/DiagnosticsWiFi.xml +++ b/data_model/1.3/clusters/DiagnosticsWiFi.xml @@ -55,14 +55,16 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + - + + + @@ -141,81 +143,81 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/data_model/1.3/clusters/DoorLock.xml b/data_model/1.3/clusters/DoorLock.xml index fcf86f3a95aa24..11b5de565e2afb 100644 --- a/data_model/1.3/clusters/DoorLock.xml +++ b/data_model/1.3/clusters/DoorLock.xml @@ -570,7 +570,7 @@ Davis, CA 95616, USA - + @@ -738,7 +738,7 @@ Davis, CA 95616, USA - + @@ -753,7 +753,7 @@ Davis, CA 95616, USA - + @@ -779,167 +779,167 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -950,7 +950,7 @@ Davis, CA 95616, USA - + @@ -961,7 +961,7 @@ Davis, CA 95616, USA - + @@ -973,7 +973,7 @@ Davis, CA 95616, USA - + @@ -986,7 +986,7 @@ Davis, CA 95616, USA - + @@ -994,12 +994,12 @@ Davis, CA 95616, USA - + - + @@ -1009,21 +1009,21 @@ Davis, CA 95616, USA - + - + - + @@ -1033,7 +1033,7 @@ Davis, CA 95616, USA - + @@ -1043,14 +1043,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/ElectricalEnergyMeasurement.xml b/data_model/1.3/clusters/ElectricalEnergyMeasurement.xml index f8bbec4c03db95..9a4012eebc5327 100644 --- a/data_model/1.3/clusters/ElectricalEnergyMeasurement.xml +++ b/data_model/1.3/clusters/ElectricalEnergyMeasurement.xml @@ -135,12 +135,12 @@ Davis, CA 95616, USA - + - + @@ -150,7 +150,7 @@ Davis, CA 95616, USA - + @@ -160,7 +160,7 @@ Davis, CA 95616, USA - + @@ -170,7 +170,7 @@ Davis, CA 95616, USA - + @@ -180,7 +180,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ElectricalPowerMeasurement.xml b/data_model/1.3/clusters/ElectricalPowerMeasurement.xml index cfb8ce9018e73c..3f4e79ccdefcec 100644 --- a/data_model/1.3/clusters/ElectricalPowerMeasurement.xml +++ b/data_model/1.3/clusters/ElectricalPowerMeasurement.xml @@ -170,39 +170,39 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -210,7 +210,7 @@ Davis, CA 95616, USA - + @@ -218,13 +218,13 @@ Davis, CA 95616, USA - + - + @@ -232,7 +232,7 @@ Davis, CA 95616, USA - + @@ -240,7 +240,7 @@ Davis, CA 95616, USA - + @@ -248,7 +248,7 @@ Davis, CA 95616, USA - + @@ -256,7 +256,7 @@ Davis, CA 95616, USA - + @@ -264,7 +264,7 @@ Davis, CA 95616, USA - + @@ -273,7 +273,7 @@ Davis, CA 95616, USA - + @@ -282,7 +282,7 @@ Davis, CA 95616, USA - + @@ -290,7 +290,7 @@ Davis, CA 95616, USA - + @@ -298,7 +298,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/EnergyEVSE.xml b/data_model/1.3/clusters/EnergyEVSE.xml index 4b881f5a1135a4..13052281c5157c 100644 --- a/data_model/1.3/clusters/EnergyEVSE.xml +++ b/data_model/1.3/clusters/EnergyEVSE.xml @@ -252,7 +252,7 @@ Davis, CA 95616, USA - + @@ -265,37 +265,37 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -303,33 +303,33 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -337,14 +337,14 @@ Davis, CA 95616, USA - + - + @@ -352,14 +352,14 @@ Davis, CA 95616, USA - + - + @@ -367,7 +367,7 @@ Davis, CA 95616, USA - + @@ -375,23 +375,23 @@ Davis, CA 95616, USA - + - + - + - + diff --git a/data_model/1.3/clusters/EnergyPreference.xml b/data_model/1.3/clusters/EnergyPreference.xml index eafb527a868b22..c43161d8dff6f9 100644 --- a/data_model/1.3/clusters/EnergyPreference.xml +++ b/data_model/1.3/clusters/EnergyPreference.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + @@ -102,7 +104,7 @@ Davis, CA 95616, USA - + @@ -110,7 +112,7 @@ Davis, CA 95616, USA - + @@ -118,7 +120,7 @@ Davis, CA 95616, USA - + @@ -127,7 +129,7 @@ Davis, CA 95616, USA - + @@ -135,7 +137,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/FanControl.xml b/data_model/1.3/clusters/FanControl.xml index 224f811261f68b..1016b8923ba308 100644 --- a/data_model/1.3/clusters/FanControl.xml +++ b/data_model/1.3/clusters/FanControl.xml @@ -119,36 +119,36 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -187,13 +187,13 @@ Davis, CA 95616, USA - + - + @@ -201,13 +201,13 @@ Davis, CA 95616, USA - + - + @@ -218,7 +218,7 @@ Davis, CA 95616, USA - + @@ -226,7 +226,7 @@ Davis, CA 95616, USA - + @@ -234,7 +234,7 @@ Davis, CA 95616, USA - + @@ -242,7 +242,7 @@ Davis, CA 95616, USA - + @@ -250,7 +250,7 @@ Davis, CA 95616, USA - + @@ -258,7 +258,7 @@ Davis, CA 95616, USA - + @@ -266,7 +266,7 @@ Davis, CA 95616, USA - + @@ -274,7 +274,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/FlowMeasurement.xml b/data_model/1.3/clusters/FlowMeasurement.xml index 71178874d57c14..717641eacb84eb 100644 --- a/data_model/1.3/clusters/FlowMeasurement.xml +++ b/data_model/1.3/clusters/FlowMeasurement.xml @@ -70,19 +70,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/1.3/clusters/GeneralCommissioningCluster.xml b/data_model/1.3/clusters/GeneralCommissioningCluster.xml index e440222780ea02..285bb4455d8f49 100644 --- a/data_model/1.3/clusters/GeneralCommissioningCluster.xml +++ b/data_model/1.3/clusters/GeneralCommissioningCluster.xml @@ -109,7 +109,7 @@ Davis, CA 95616, USA - + @@ -119,12 +119,12 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/Group-Key-Management-Cluster.xml b/data_model/1.3/clusters/Group-Key-Management-Cluster.xml index c1819628e34d7b..4e9ae482a064ed 100644 --- a/data_model/1.3/clusters/Group-Key-Management-Cluster.xml +++ b/data_model/1.3/clusters/Group-Key-Management-Cluster.xml @@ -167,7 +167,7 @@ Davis, CA 95616, USA - + @@ -179,12 +179,12 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/Groups.xml b/data_model/1.3/clusters/Groups.xml index 1f168e13fad933..6c53c1a602f255 100644 --- a/data_model/1.3/clusters/Groups.xml +++ b/data_model/1.3/clusters/Groups.xml @@ -83,7 +83,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ICDManagement.xml b/data_model/1.3/clusters/ICDManagement.xml index 512dfd119efef7..b1b478a166ee80 100644 --- a/data_model/1.3/clusters/ICDManagement.xml +++ b/data_model/1.3/clusters/ICDManagement.xml @@ -120,24 +120,24 @@ Davis, CA 95616, USA - + - + - + - + @@ -145,14 +145,14 @@ Davis, CA 95616, USA - + - + @@ -160,7 +160,7 @@ Davis, CA 95616, USA - + @@ -171,7 +171,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/IlluminanceMeasurement.xml b/data_model/1.3/clusters/IlluminanceMeasurement.xml index d3228b845ca058..02aa466de6b8a6 100644 --- a/data_model/1.3/clusters/IlluminanceMeasurement.xml +++ b/data_model/1.3/clusters/IlluminanceMeasurement.xml @@ -83,20 +83,20 @@ Davis, CA 95616, USA - + - + - + @@ -107,7 +107,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/Label-Cluster-FixedLabelCluster.xml b/data_model/1.3/clusters/Label-Cluster-FixedLabelCluster.xml index 98106b6fc33e40..b915e77bb5a01f 100644 --- a/data_model/1.3/clusters/Label-Cluster-FixedLabelCluster.xml +++ b/data_model/1.3/clusters/Label-Cluster-FixedLabelCluster.xml @@ -70,7 +70,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/Label-Cluster-LabelCluster.xml b/data_model/1.3/clusters/Label-Cluster-LabelCluster.xml index 0ca5566f0dc132..43148b6dc9186f 100644 --- a/data_model/1.3/clusters/Label-Cluster-LabelCluster.xml +++ b/data_model/1.3/clusters/Label-Cluster-LabelCluster.xml @@ -80,7 +80,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/Label-Cluster-UserLabelCluster.xml b/data_model/1.3/clusters/Label-Cluster-UserLabelCluster.xml index eba0099ffb59d2..40dac53a4242cd 100644 --- a/data_model/1.3/clusters/Label-Cluster-UserLabelCluster.xml +++ b/data_model/1.3/clusters/Label-Cluster-UserLabelCluster.xml @@ -70,7 +70,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/LaundryDryerControls.xml b/data_model/1.3/clusters/LaundryDryerControls.xml index af4f787c0432b7..d860d2ef9dcf21 100644 --- a/data_model/1.3/clusters/LaundryDryerControls.xml +++ b/data_model/1.3/clusters/LaundryDryerControls.xml @@ -88,7 +88,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/LaundryWasherControls.xml b/data_model/1.3/clusters/LaundryWasherControls.xml index 6c4f4bc0b0c3a5..2718142b74f991 100644 --- a/data_model/1.3/clusters/LaundryWasherControls.xml +++ b/data_model/1.3/clusters/LaundryWasherControls.xml @@ -108,7 +108,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/LevelControl.xml b/data_model/1.3/clusters/LevelControl.xml index fa6cbe397a672a..2753325511ada6 100644 --- a/data_model/1.3/clusters/LevelControl.xml +++ b/data_model/1.3/clusters/LevelControl.xml @@ -68,7 +68,9 @@ Davis, CA 95616, USA - + + + @@ -120,7 +122,7 @@ Davis, CA 95616, USA - + @@ -153,7 +155,7 @@ Davis, CA 95616, USA - + @@ -184,28 +186,28 @@ Davis, CA 95616, USA - + - + - + - + - + diff --git a/data_model/1.3/clusters/LocalizationConfiguration.xml b/data_model/1.3/clusters/LocalizationConfiguration.xml index 66809f545389be..7ddfba8efcc9cb 100644 --- a/data_model/1.3/clusters/LocalizationConfiguration.xml +++ b/data_model/1.3/clusters/LocalizationConfiguration.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - + @@ -75,7 +75,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/LocalizationTimeFormat.xml b/data_model/1.3/clusters/LocalizationTimeFormat.xml index db8b809b0341a9..2ede281c7352a9 100644 --- a/data_model/1.3/clusters/LocalizationTimeFormat.xml +++ b/data_model/1.3/clusters/LocalizationTimeFormat.xml @@ -125,12 +125,12 @@ Davis, CA 95616, USA - + - + @@ -138,7 +138,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/LocalizationUnit.xml b/data_model/1.3/clusters/LocalizationUnit.xml index 2c6e1ecbd648e6..0157ebb53b0d39 100644 --- a/data_model/1.3/clusters/LocalizationUnit.xml +++ b/data_model/1.3/clusters/LocalizationUnit.xml @@ -84,7 +84,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/MediaPlayback.xml b/data_model/1.3/clusters/MediaPlayback.xml index 03175277dc12c5..dae60d7a1b2572 100644 --- a/data_model/1.3/clusters/MediaPlayback.xml +++ b/data_model/1.3/clusters/MediaPlayback.xml @@ -223,7 +223,7 @@ Davis, CA 95616, USA - + @@ -231,7 +231,7 @@ Davis, CA 95616, USA - + @@ -239,7 +239,7 @@ Davis, CA 95616, USA - + @@ -254,7 +254,7 @@ Davis, CA 95616, USA - + @@ -262,7 +262,7 @@ Davis, CA 95616, USA - + @@ -270,7 +270,7 @@ Davis, CA 95616, USA - + @@ -279,7 +279,7 @@ Davis, CA 95616, USA - + @@ -287,7 +287,7 @@ Davis, CA 95616, USA - + @@ -296,7 +296,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/MicrowaveOvenControl.xml b/data_model/1.3/clusters/MicrowaveOvenControl.xml index ecc9d23b143d4b..5c92c309d6de00 100644 --- a/data_model/1.3/clusters/MicrowaveOvenControl.xml +++ b/data_model/1.3/clusters/MicrowaveOvenControl.xml @@ -89,7 +89,7 @@ Davis, CA 95616, USA - + @@ -102,7 +102,7 @@ Davis, CA 95616, USA - + @@ -110,7 +110,7 @@ Davis, CA 95616, USA - + @@ -118,7 +118,7 @@ Davis, CA 95616, USA - + @@ -127,7 +127,7 @@ Davis, CA 95616, USA - + @@ -148,7 +148,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ModeBase.xml b/data_model/1.3/clusters/ModeBase.xml index dcd6cf1c448028..0fcc581d07aaf1 100644 --- a/data_model/1.3/clusters/ModeBase.xml +++ b/data_model/1.3/clusters/ModeBase.xml @@ -99,25 +99,25 @@ Require at least one standard mode tag. Define reserved ranges for base/derived - + - + - + - + @@ -134,7 +134,6 @@ Require at least one standard mode tag. Define reserved ranges for base/derived - diff --git a/data_model/1.3/clusters/ModeSelect.xml b/data_model/1.3/clusters/ModeSelect.xml index cfdf7adb92761c..76ebf5874af273 100644 --- a/data_model/1.3/clusters/ModeSelect.xml +++ b/data_model/1.3/clusters/ModeSelect.xml @@ -97,38 +97,38 @@ Davis, CA 95616, USA - + - + - + - + - + - + diff --git a/data_model/1.3/clusters/Mode_DeviceEnergyManagement.xml b/data_model/1.3/clusters/Mode_DeviceEnergyManagement.xml index e167e8649650ba..ff849a081ff573 100644 --- a/data_model/1.3/clusters/Mode_DeviceEnergyManagement.xml +++ b/data_model/1.3/clusters/Mode_DeviceEnergyManagement.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/1.3/clusters/NetworkCommissioningCluster.xml b/data_model/1.3/clusters/NetworkCommissioningCluster.xml index 855947e5dda349..fdd404312f446d 100644 --- a/data_model/1.3/clusters/NetworkCommissioningCluster.xml +++ b/data_model/1.3/clusters/NetworkCommissioningCluster.xml @@ -161,13 +161,13 @@ Davis, CA 95616, USA - + - + - + @@ -262,7 +262,7 @@ Davis, CA 95616, USA - + @@ -274,7 +274,7 @@ Davis, CA 95616, USA - + @@ -285,7 +285,7 @@ Davis, CA 95616, USA - + @@ -296,29 +296,29 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -326,14 +326,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/OTARequestor.xml b/data_model/1.3/clusters/OTARequestor.xml index f6a5ff0365abed..3a562c9f18a046 100644 --- a/data_model/1.3/clusters/OTARequestor.xml +++ b/data_model/1.3/clusters/OTARequestor.xml @@ -149,7 +149,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/OccupancySensing.xml b/data_model/1.3/clusters/OccupancySensing.xml index 48756121d24769..b576e91078e663 100644 --- a/data_model/1.3/clusters/OccupancySensing.xml +++ b/data_model/1.3/clusters/OccupancySensing.xml @@ -103,7 +103,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/OnOff.xml b/data_model/1.3/clusters/OnOff.xml index 9366985e5ce35e..1072b96d56a243 100644 --- a/data_model/1.3/clusters/OnOff.xml +++ b/data_model/1.3/clusters/OnOff.xml @@ -145,7 +145,7 @@ Davis, CA 95616, USA - + @@ -168,7 +168,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/OperationalCredentialCluster.xml b/data_model/1.3/clusters/OperationalCredentialCluster.xml index 2aa070f96b2573..b3811db4a5774a 100644 --- a/data_model/1.3/clusters/OperationalCredentialCluster.xml +++ b/data_model/1.3/clusters/OperationalCredentialCluster.xml @@ -155,26 +155,26 @@ Davis, CA 95616, USA - + - + - + - + @@ -183,7 +183,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/OperationalState.xml b/data_model/1.3/clusters/OperationalState.xml index 3648a8c81ec8f4..44567fa726f6fd 100644 --- a/data_model/1.3/clusters/OperationalState.xml +++ b/data_model/1.3/clusters/OperationalState.xml @@ -114,19 +114,19 @@ Davis, CA 95616, USA - + - + - + @@ -179,7 +179,6 @@ Davis, CA 95616, USA - diff --git a/data_model/1.3/clusters/PowerSourceCluster.xml b/data_model/1.3/clusters/PowerSourceCluster.xml index 1c01cc548bfdee..4596880e32b938 100644 --- a/data_model/1.3/clusters/PowerSourceCluster.xml +++ b/data_model/1.3/clusters/PowerSourceCluster.xml @@ -556,32 +556,32 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -589,21 +589,21 @@ Davis, CA 95616, USA - + - + - + @@ -624,14 +624,14 @@ Davis, CA 95616, USA - + - + @@ -639,7 +639,7 @@ Davis, CA 95616, USA - + @@ -659,7 +659,7 @@ Davis, CA 95616, USA - + @@ -680,7 +680,7 @@ Davis, CA 95616, USA - + @@ -688,7 +688,7 @@ Davis, CA 95616, USA - + @@ -696,7 +696,7 @@ Davis, CA 95616, USA - + @@ -704,7 +704,7 @@ Davis, CA 95616, USA - + @@ -712,7 +712,7 @@ Davis, CA 95616, USA - + @@ -720,7 +720,7 @@ Davis, CA 95616, USA - + @@ -730,7 +730,7 @@ Davis, CA 95616, USA - + @@ -744,7 +744,7 @@ Davis, CA 95616, USA - + @@ -757,7 +757,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/PowerSourceConfigurationCluster.xml b/data_model/1.3/clusters/PowerSourceConfigurationCluster.xml index 6a47ce1b54cdbd..5348f6f0b091b6 100644 --- a/data_model/1.3/clusters/PowerSourceConfigurationCluster.xml +++ b/data_model/1.3/clusters/PowerSourceConfigurationCluster.xml @@ -67,7 +67,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/PowerTopology.xml b/data_model/1.3/clusters/PowerTopology.xml index 4ebdda614a4aec..b958d03c01aeb1 100644 --- a/data_model/1.3/clusters/PowerTopology.xml +++ b/data_model/1.3/clusters/PowerTopology.xml @@ -83,7 +83,7 @@ Davis, CA 95616, USA - + @@ -92,7 +92,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/PressureMeasurement.xml b/data_model/1.3/clusters/PressureMeasurement.xml index a46e911253941f..bf9b6a9286e381 100644 --- a/data_model/1.3/clusters/PressureMeasurement.xml +++ b/data_model/1.3/clusters/PressureMeasurement.xml @@ -75,19 +75,19 @@ Davis, CA 95616, USA - + - + - + @@ -98,7 +98,7 @@ Davis, CA 95616, USA - + @@ -106,7 +106,7 @@ Davis, CA 95616, USA - + @@ -114,7 +114,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ProxyConfiguration-Cluster.xml b/data_model/1.3/clusters/ProxyConfiguration-Cluster.xml index 8ad566ec8527b2..c33ed5cd03b841 100644 --- a/data_model/1.3/clusters/ProxyConfiguration-Cluster.xml +++ b/data_model/1.3/clusters/ProxyConfiguration-Cluster.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + @@ -82,7 +84,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ProxyDiscovery-Cluster.xml b/data_model/1.3/clusters/ProxyDiscovery-Cluster.xml index 6fa4a9eb6f3a06..159bdff7333853 100644 --- a/data_model/1.3/clusters/ProxyDiscovery-Cluster.xml +++ b/data_model/1.3/clusters/ProxyDiscovery-Cluster.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/1.3/clusters/PumpConfigurationControl.xml b/data_model/1.3/clusters/PumpConfigurationControl.xml index 79fafe659c95e2..b197f63bb4373f 100644 --- a/data_model/1.3/clusters/PumpConfigurationControl.xml +++ b/data_model/1.3/clusters/PumpConfigurationControl.xml @@ -175,22 +175,22 @@ Davis, CA 95616, USA - + - + - + - + @@ -202,7 +202,7 @@ Davis, CA 95616, USA - + @@ -214,7 +214,7 @@ Davis, CA 95616, USA - + @@ -226,7 +226,7 @@ Davis, CA 95616, USA - + @@ -238,7 +238,7 @@ Davis, CA 95616, USA - + @@ -250,7 +250,7 @@ Davis, CA 95616, USA - + @@ -262,7 +262,7 @@ Davis, CA 95616, USA - + @@ -274,7 +274,7 @@ Davis, CA 95616, USA - + @@ -286,7 +286,7 @@ Davis, CA 95616, USA - + @@ -299,7 +299,7 @@ Davis, CA 95616, USA - + @@ -312,62 +312,62 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + diff --git a/data_model/1.3/clusters/ResourceMonitoring.xml b/data_model/1.3/clusters/ResourceMonitoring.xml index 6b0e8f3a203ded..09cc479618295f 100644 --- a/data_model/1.3/clusters/ResourceMonitoring.xml +++ b/data_model/1.3/clusters/ResourceMonitoring.xml @@ -62,8 +62,8 @@ Davis, CA 95616, USA - - + + @@ -73,7 +73,7 @@ Davis, CA 95616, USA - + @@ -103,13 +103,13 @@ Davis, CA 95616, USA - + - + @@ -136,7 +136,7 @@ Davis, CA 95616, USA - + @@ -152,13 +152,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/Scenes.xml b/data_model/1.3/clusters/Scenes.xml index 9150a754d3041a..2bbd2e246a06cc 100644 --- a/data_model/1.3/clusters/Scenes.xml +++ b/data_model/1.3/clusters/Scenes.xml @@ -1,61 +1,61 @@ - @@ -165,12 +165,12 @@ Davis, CA 95616, USA - + - + @@ -398,4 +398,4 @@ Davis, CA 95616, USA - + \ No newline at end of file diff --git a/data_model/1.3/clusters/SmokeCOAlarm.xml b/data_model/1.3/clusters/SmokeCOAlarm.xml index 25c034ac94082c..4ba9bd2708b476 100644 --- a/data_model/1.3/clusters/SmokeCOAlarm.xml +++ b/data_model/1.3/clusters/SmokeCOAlarm.xml @@ -163,31 +163,31 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -196,12 +196,12 @@ Davis, CA 95616, USA - + - + @@ -226,7 +226,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/Switch.xml b/data_model/1.3/clusters/Switch.xml index c7b607c637c74c..14912208782baa 100644 --- a/data_model/1.3/clusters/Switch.xml +++ b/data_model/1.3/clusters/Switch.xml @@ -95,19 +95,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/1.3/clusters/TemperatureControl.xml b/data_model/1.3/clusters/TemperatureControl.xml index 3f5fa9c00332d6..2f2527ce4ad0fa 100644 --- a/data_model/1.3/clusters/TemperatureControl.xml +++ b/data_model/1.3/clusters/TemperatureControl.xml @@ -86,7 +86,7 @@ Davis, CA 95616, USA - + @@ -94,7 +94,7 @@ Davis, CA 95616, USA - + @@ -102,7 +102,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/TemperatureMeasurement.xml b/data_model/1.3/clusters/TemperatureMeasurement.xml index 176fad6b246a60..0935b18edab675 100644 --- a/data_model/1.3/clusters/TemperatureMeasurement.xml +++ b/data_model/1.3/clusters/TemperatureMeasurement.xml @@ -71,19 +71,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/1.3/clusters/Thermostat.xml b/data_model/1.3/clusters/Thermostat.xml index 75640c697e0478..66d927c3bc6ad0 100644 --- a/data_model/1.3/clusters/Thermostat.xml +++ b/data_model/1.3/clusters/Thermostat.xml @@ -472,12 +472,12 @@ Davis, CA 95616, USA - + - + @@ -489,7 +489,7 @@ Davis, CA 95616, USA - + @@ -497,7 +497,7 @@ Davis, CA 95616, USA - + @@ -505,7 +505,7 @@ Davis, CA 95616, USA - + @@ -513,7 +513,7 @@ Davis, CA 95616, USA - + @@ -521,7 +521,7 @@ Davis, CA 95616, USA - + @@ -529,7 +529,7 @@ Davis, CA 95616, USA - + @@ -537,13 +537,13 @@ Davis, CA 95616, USA - + - + @@ -553,7 +553,7 @@ Davis, CA 95616, USA - + @@ -561,7 +561,7 @@ Davis, CA 95616, USA - + @@ -569,7 +569,7 @@ Davis, CA 95616, USA - + @@ -580,7 +580,7 @@ Davis, CA 95616, USA - + @@ -591,7 +591,7 @@ Davis, CA 95616, USA - + @@ -599,7 +599,7 @@ Davis, CA 95616, USA - + @@ -607,7 +607,7 @@ Davis, CA 95616, USA - + @@ -615,7 +615,7 @@ Davis, CA 95616, USA - + @@ -623,7 +623,7 @@ Davis, CA 95616, USA - + @@ -631,19 +631,19 @@ Davis, CA 95616, USA - + - + - + @@ -663,7 +663,7 @@ Davis, CA 95616, USA - + @@ -671,33 +671,33 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -713,7 +713,7 @@ Davis, CA 95616, USA - + @@ -722,7 +722,7 @@ Davis, CA 95616, USA - + @@ -730,7 +730,7 @@ Davis, CA 95616, USA - + @@ -738,7 +738,7 @@ Davis, CA 95616, USA - + @@ -746,7 +746,7 @@ Davis, CA 95616, USA - + @@ -757,7 +757,7 @@ Davis, CA 95616, USA - + @@ -768,7 +768,7 @@ Davis, CA 95616, USA - + @@ -779,29 +779,29 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -811,18 +811,18 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/1.3/clusters/TimeSync.xml b/data_model/1.3/clusters/TimeSync.xml index 9d4057db8bdb85..a506a647aeb8a3 100644 --- a/data_model/1.3/clusters/TimeSync.xml +++ b/data_model/1.3/clusters/TimeSync.xml @@ -213,7 +213,7 @@ Davis, CA 95616, USA - + @@ -228,14 +228,14 @@ Davis, CA 95616, USA - + - + @@ -244,7 +244,7 @@ Davis, CA 95616, USA - + @@ -253,21 +253,21 @@ Davis, CA 95616, USA - + - + - + @@ -280,7 +280,7 @@ Davis, CA 95616, USA - + @@ -288,7 +288,7 @@ Davis, CA 95616, USA - + @@ -296,7 +296,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ValidProxies-Cluster.xml b/data_model/1.3/clusters/ValidProxies-Cluster.xml index b9db8e1762647f..c5740c90e52433 100644 --- a/data_model/1.3/clusters/ValidProxies-Cluster.xml +++ b/data_model/1.3/clusters/ValidProxies-Cluster.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + @@ -75,7 +77,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ValveConfigurationControl.xml b/data_model/1.3/clusters/ValveConfigurationControl.xml index b0f2ec91b0fa95..86e511505fd12b 100644 --- a/data_model/1.3/clusters/ValveConfigurationControl.xml +++ b/data_model/1.3/clusters/ValveConfigurationControl.xml @@ -108,55 +108,55 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + @@ -168,7 +168,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/WakeOnLAN.xml b/data_model/1.3/clusters/WakeOnLAN.xml index 4f6e032c084b38..7f5c08bdd624ad 100644 --- a/data_model/1.3/clusters/WakeOnLAN.xml +++ b/data_model/1.3/clusters/WakeOnLAN.xml @@ -68,13 +68,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/WaterContentMeasurement.xml b/data_model/1.3/clusters/WaterContentMeasurement.xml index 85d44793c93ae4..af11c9cf8d514c 100644 --- a/data_model/1.3/clusters/WaterContentMeasurement.xml +++ b/data_model/1.3/clusters/WaterContentMeasurement.xml @@ -70,19 +70,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/1.3/clusters/WindowCovering.xml b/data_model/1.3/clusters/WindowCovering.xml index af59da5a9f72de..88d7e3dc512cba 100644 --- a/data_model/1.3/clusters/WindowCovering.xml +++ b/data_model/1.3/clusters/WindowCovering.xml @@ -391,13 +391,13 @@ Davis, CA 95616, USA - + - + @@ -408,7 +408,7 @@ Davis, CA 95616, USA - + @@ -419,7 +419,7 @@ Davis, CA 95616, USA - + @@ -431,7 +431,7 @@ Davis, CA 95616, USA - + @@ -443,27 +443,27 @@ Davis, CA 95616, USA - + - + - + - + @@ -473,7 +473,7 @@ Davis, CA 95616, USA - + @@ -484,13 +484,13 @@ Davis, CA 95616, USA - + - + @@ -500,7 +500,7 @@ Davis, CA 95616, USA - + @@ -510,13 +510,13 @@ Davis, CA 95616, USA - + - + @@ -527,7 +527,7 @@ Davis, CA 95616, USA - + @@ -538,7 +538,7 @@ Davis, CA 95616, USA - + @@ -550,7 +550,7 @@ Davis, CA 95616, USA - + @@ -562,7 +562,7 @@ Davis, CA 95616, USA - + @@ -574,7 +574,7 @@ Davis, CA 95616, USA - + @@ -595,7 +595,7 @@ Davis, CA 95616, USA - + @@ -607,7 +607,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/cluster_ids.json b/data_model/1.3/clusters/cluster_ids.json index 40a46edd00722e..82a258ee0c6d7f 100644 --- a/data_model/1.3/clusters/cluster_ids.json +++ b/data_model/1.3/clusters/cluster_ids.json @@ -22,7 +22,7 @@ "51": "General Diagnostics", "52": "Software Diagnostics", "53": "Thread Network Diagnostics", - "54": "Wi", + "54": "Wi-Fi Network Diagnostics", "55": "Ethernet Network Diagnostics", "56": "Time Synchronization", "57": "Bridged Device Basic Information", @@ -88,7 +88,7 @@ "1037": "Carbon Dioxide Concentration Measurement", "1043": "Nitrogen Dioxide Concentration Measurement", "1045": "Ozone Concentration Measurement", - "1066": "PM2", + "1066": "PM2.5 Concentration Measurement", "1067": "Formaldehyde Concentration Measurement", "1068": "PM1 Concentration Measurement", "1069": "PM10 Concentration Measurement", diff --git a/data_model/1.3/device_types/AirQualitySensor.xml b/data_model/1.3/device_types/AirQualitySensor.xml index 602781819d1696..bf56eb754f24c6 100644 --- a/data_model/1.3/device_types/AirQualitySensor.xml +++ b/data_model/1.3/device_types/AirQualitySensor.xml @@ -86,7 +86,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/device_types/DimmablePlug-InUnit.xml b/data_model/1.3/device_types/DimmablePlug-InUnit.xml index 4d344bfc9fb89c..65f6b6e1dd2e9c 100644 --- a/data_model/1.3/device_types/DimmablePlug-InUnit.xml +++ b/data_model/1.3/device_types/DimmablePlug-InUnit.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/1.3/device_types/DoorLockController.xml b/data_model/1.3/device_types/DoorLockController.xml index 4d031a37be1eec..64d26eba8d8eeb 100644 --- a/data_model/1.3/device_types/DoorLockController.xml +++ b/data_model/1.3/device_types/DoorLockController.xml @@ -74,10 +74,7 @@ Davis, CA 95616, USA - - - - + diff --git a/data_model/1.3/device_types/OnOffPlug-inUnit.xml b/data_model/1.3/device_types/OnOffPlug-inUnit.xml index 3be1ed0f9eb13d..888f365bed0b83 100644 --- a/data_model/1.3/device_types/OnOffPlug-inUnit.xml +++ b/data_model/1.3/device_types/OnOffPlug-inUnit.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/1.3/device_types/RootNodeDeviceType.xml b/data_model/1.3/device_types/RootNodeDeviceType.xml index c2028f07d91548..0288e8848cb321 100644 --- a/data_model/1.3/device_types/RootNodeDeviceType.xml +++ b/data_model/1.3/device_types/RootNodeDeviceType.xml @@ -124,7 +124,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/device_types/Thermostat.xml b/data_model/1.3/device_types/Thermostat.xml index 49ba4b6779f084..62c7060bf03584 100644 --- a/data_model/1.3/device_types/Thermostat.xml +++ b/data_model/1.3/device_types/Thermostat.xml @@ -83,16 +83,10 @@ Davis, CA 95616, USA - - - - + - - - - + diff --git a/data_model/1.3/scraper_version b/data_model/1.3/scraper_version index e8ea05db81420d..c813fe116c9f9e 100644 --- a/data_model/1.3/scraper_version +++ b/data_model/1.3/scraper_version @@ -1 +1 @@ -1.2.4 +1.2.5 diff --git a/data_model/1.3/spec_sha b/data_model/1.3/spec_sha index 274f0d55122714..9166e9f7a4977c 100644 --- a/data_model/1.3/spec_sha +++ b/data_model/1.3/spec_sha @@ -1 +1 @@ -ab9cf4653d40fe9193bbc7fe9febf74c08bf7dfa +6b8d0a46a59d5ec5e2d2662e0b4a0b4810118bd6 diff --git a/data_model/master/clusters/ACL-Cluster.xml b/data_model/master/clusters/ACL-Cluster.xml index 5c4c96a687cb13..d5fbf419ba4daf 100644 --- a/data_model/master/clusters/ACL-Cluster.xml +++ b/data_model/master/clusters/ACL-Cluster.xml @@ -180,19 +180,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/master/clusters/AdminCommissioningCluster.xml b/data_model/master/clusters/AdminCommissioningCluster.xml index ccbb579134dc00..8e95e46f128db0 100644 --- a/data_model/master/clusters/AdminCommissioningCluster.xml +++ b/data_model/master/clusters/AdminCommissioningCluster.xml @@ -91,12 +91,12 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/AlarmBase.xml b/data_model/master/clusters/AlarmBase.xml index fd0ccb5bc19d46..e374dcc382d208 100644 --- a/data_model/master/clusters/AlarmBase.xml +++ b/data_model/master/clusters/AlarmBase.xml @@ -80,7 +80,7 @@ Davis, CA 95616, USA - + @@ -91,7 +91,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ApplicationBasic.xml b/data_model/master/clusters/ApplicationBasic.xml index ee39b8a421209d..28e47e7800352e 100644 --- a/data_model/master/clusters/ApplicationBasic.xml +++ b/data_model/master/clusters/ApplicationBasic.xml @@ -92,29 +92,29 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -125,14 +125,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/ApplicationLauncher.xml b/data_model/master/clusters/ApplicationLauncher.xml index 57d6858dd8ce14..27fa528a81e8cf 100644 --- a/data_model/master/clusters/ApplicationLauncher.xml +++ b/data_model/master/clusters/ApplicationLauncher.xml @@ -103,14 +103,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/BallastConfiguration.xml b/data_model/master/clusters/BallastConfiguration.xml index 0f37d86067e994..9dbf4e61887d76 100644 --- a/data_model/master/clusters/BallastConfiguration.xml +++ b/data_model/master/clusters/BallastConfiguration.xml @@ -65,7 +65,9 @@ Davis, CA 95616, USA - + + + @@ -116,12 +118,12 @@ Davis, CA 95616, USA - + - + @@ -141,12 +143,12 @@ Davis, CA 95616, USA - + - + @@ -155,7 +157,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/BasicInformationCluster.xml b/data_model/master/clusters/BasicInformationCluster.xml index 428c683a0ea803..538b4f5e9e9f8b 100644 --- a/data_model/master/clusters/BasicInformationCluster.xml +++ b/data_model/master/clusters/BasicInformationCluster.xml @@ -54,8 +54,6 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA - -:xrefstyle: basic --> @@ -182,100 +180,100 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -284,35 +282,35 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -322,6 +320,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/master/clusters/Binding-Cluster.xml b/data_model/master/clusters/Binding-Cluster.xml index 444c99b315348d..055725f0b9ee47 100644 --- a/data_model/master/clusters/Binding-Cluster.xml +++ b/data_model/master/clusters/Binding-Cluster.xml @@ -97,7 +97,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/BooleanState.xml b/data_model/master/clusters/BooleanState.xml index 5bb29f53ae0c3e..ddb16e26a1d6ad 100644 --- a/data_model/master/clusters/BooleanState.xml +++ b/data_model/master/clusters/BooleanState.xml @@ -68,7 +68,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/BooleanStateConfiguration.xml b/data_model/master/clusters/BooleanStateConfiguration.xml index 01444d565294b3..719cd9569b5ae2 100644 --- a/data_model/master/clusters/BooleanStateConfiguration.xml +++ b/data_model/master/clusters/BooleanStateConfiguration.xml @@ -106,7 +106,7 @@ Davis, CA 95616, USA - + @@ -114,7 +114,7 @@ Davis, CA 95616, USA - + @@ -122,7 +122,7 @@ Davis, CA 95616, USA - + @@ -145,7 +145,7 @@ Davis, CA 95616, USA - + @@ -155,7 +155,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Channel.xml b/data_model/master/clusters/Channel.xml index 17144c9032c3e5..6177bfe6a652cc 100644 --- a/data_model/master/clusters/Channel.xml +++ b/data_model/master/clusters/Channel.xml @@ -307,7 +307,7 @@ Davis, CA 95616, USA - + @@ -315,7 +315,7 @@ Davis, CA 95616, USA - + @@ -366,6 +366,7 @@ Davis, CA 95616, USA + @@ -400,6 +401,7 @@ Davis, CA 95616, USA + @@ -412,6 +414,7 @@ Davis, CA 95616, USA + @@ -437,6 +440,7 @@ Davis, CA 95616, USA + diff --git a/data_model/master/clusters/ColorControl.xml b/data_model/master/clusters/ColorControl.xml index 90d999fa20b4ac..6901b6ee4130c6 100644 --- a/data_model/master/clusters/ColorControl.xml +++ b/data_model/master/clusters/ColorControl.xml @@ -65,7 +65,8 @@ Davis, CA 95616, USA - + @@ -111,19 +112,10 @@ Davis, CA 95616, USA - + - - - - - - - - - - + @@ -252,7 +244,7 @@ Davis, CA 95616, USA - + @@ -260,7 +252,7 @@ Davis, CA 95616, USA - + @@ -268,13 +260,13 @@ Davis, CA 95616, USA - + - + @@ -282,7 +274,7 @@ Davis, CA 95616, USA - + @@ -299,7 +291,7 @@ Davis, CA 95616, USA - + @@ -307,7 +299,7 @@ Davis, CA 95616, USA - + @@ -317,13 +309,13 @@ Davis, CA 95616, USA - + - + @@ -337,7 +329,7 @@ Davis, CA 95616, USA - + @@ -351,7 +343,7 @@ Davis, CA 95616, USA - + @@ -364,7 +356,7 @@ Davis, CA 95616, USA - + @@ -378,7 +370,7 @@ Davis, CA 95616, USA - + @@ -392,7 +384,7 @@ Davis, CA 95616, USA - + @@ -405,7 +397,7 @@ Davis, CA 95616, USA - + @@ -419,7 +411,7 @@ Davis, CA 95616, USA - + @@ -433,7 +425,7 @@ Davis, CA 95616, USA - + @@ -446,7 +438,7 @@ Davis, CA 95616, USA - + @@ -460,7 +452,7 @@ Davis, CA 95616, USA - + @@ -474,7 +466,7 @@ Davis, CA 95616, USA - + @@ -487,7 +479,7 @@ Davis, CA 95616, USA - + @@ -501,7 +493,7 @@ Davis, CA 95616, USA - + @@ -515,7 +507,7 @@ Davis, CA 95616, USA - + @@ -528,7 +520,7 @@ Davis, CA 95616, USA - + @@ -542,7 +534,7 @@ Davis, CA 95616, USA - + @@ -556,7 +548,7 @@ Davis, CA 95616, USA - + @@ -589,7 +581,7 @@ Davis, CA 95616, USA - + @@ -604,7 +596,7 @@ Davis, CA 95616, USA - + @@ -619,24 +611,24 @@ Davis, CA 95616, USA - + - + - + - + @@ -644,7 +636,7 @@ Davis, CA 95616, USA - + @@ -652,7 +644,7 @@ Davis, CA 95616, USA - + @@ -696,11 +688,11 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/ConcentrationMeasurement.xml b/data_model/master/clusters/ConcentrationMeasurement.xml index 4b51cffa124321..b622a3560b4ff0 100644 --- a/data_model/master/clusters/ConcentrationMeasurement.xml +++ b/data_model/master/clusters/ConcentrationMeasurement.xml @@ -62,16 +62,16 @@ Davis, CA 95616, USA - - - - - - - - - - + + + + + + + + + + @@ -181,7 +181,7 @@ Davis, CA 95616, USA - + @@ -189,7 +189,7 @@ Davis, CA 95616, USA - + @@ -197,7 +197,7 @@ Davis, CA 95616, USA - + @@ -205,7 +205,7 @@ Davis, CA 95616, USA - + @@ -213,7 +213,7 @@ Davis, CA 95616, USA - + @@ -221,7 +221,7 @@ Davis, CA 95616, USA - + @@ -229,7 +229,7 @@ Davis, CA 95616, USA - + @@ -244,14 +244,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/ContentControl.xml b/data_model/master/clusters/ContentControl.xml index b2539cf445c289..6848886c43ac02 100644 --- a/data_model/master/clusters/ContentControl.xml +++ b/data_model/master/clusters/ContentControl.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/master/clusters/ContentLauncher.xml b/data_model/master/clusters/ContentLauncher.xml index 9a5674efa8eb64..b4d6e7fa26500c 100644 --- a/data_model/master/clusters/ContentLauncher.xml +++ b/data_model/master/clusters/ContentLauncher.xml @@ -299,7 +299,7 @@ Davis, CA 95616, USA - + @@ -307,7 +307,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/DemandResponseLoadControl.xml b/data_model/master/clusters/DemandResponseLoadControl.xml index c20a7c3b7f013f..1acd1ea26c6088 100644 --- a/data_model/master/clusters/DemandResponseLoadControl.xml +++ b/data_model/master/clusters/DemandResponseLoadControl.xml @@ -311,51 +311,51 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + diff --git a/data_model/master/clusters/Descriptor-Cluster.xml b/data_model/master/clusters/Descriptor-Cluster.xml index 94d262473d4c9c..9c0bcf0b2348e3 100644 --- a/data_model/master/clusters/Descriptor-Cluster.xml +++ b/data_model/master/clusters/Descriptor-Cluster.xml @@ -85,20 +85,20 @@ Davis, CA 95616, USA - + - + - + @@ -109,7 +109,7 @@ Davis, CA 95616, USA - + @@ -117,7 +117,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/DeviceEnergyManagement.xml b/data_model/master/clusters/DeviceEnergyManagement.xml index ee1b2f0f2725e6..efc027f27cdeee 100644 --- a/data_model/master/clusters/DeviceEnergyManagement.xml +++ b/data_model/master/clusters/DeviceEnergyManagement.xml @@ -65,7 +65,9 @@ Davis, CA 95616, USA - + + + @@ -118,6 +120,7 @@ Davis, CA 95616, USA + @@ -472,12 +475,12 @@ Davis, CA 95616, USA - + - + @@ -495,14 +498,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/DiagnosticsEthernet.xml b/data_model/master/clusters/DiagnosticsEthernet.xml index dfcd3d11c41f52..fd2bb0341ca06c 100644 --- a/data_model/master/clusters/DiagnosticsEthernet.xml +++ b/data_model/master/clusters/DiagnosticsEthernet.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + @@ -108,57 +110,57 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + diff --git a/data_model/master/clusters/DiagnosticsGeneral.xml b/data_model/master/clusters/DiagnosticsGeneral.xml index 4da912b03dc3df..ff78100fe3a7d3 100644 --- a/data_model/master/clusters/DiagnosticsGeneral.xml +++ b/data_model/master/clusters/DiagnosticsGeneral.xml @@ -223,17 +223,17 @@ Davis, CA 95616, USA - + - + - + @@ -310,7 +310,6 @@ Davis, CA 95616, USA - diff --git a/data_model/master/clusters/DiagnosticsSoftware.xml b/data_model/master/clusters/DiagnosticsSoftware.xml index 7cb3c9ff39ad2f..c7ee8ee842bf02 100644 --- a/data_model/master/clusters/DiagnosticsSoftware.xml +++ b/data_model/master/clusters/DiagnosticsSoftware.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/master/clusters/DiagnosticsThread.xml b/data_model/master/clusters/DiagnosticsThread.xml index 120efaddf8c08e..1da3eba21a4e4e 100644 --- a/data_model/master/clusters/DiagnosticsThread.xml +++ b/data_model/master/clusters/DiagnosticsThread.xml @@ -63,7 +63,9 @@ Davis, CA 95616, USA - + + + @@ -257,38 +259,38 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + @@ -305,356 +307,356 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/data_model/master/clusters/DiagnosticsWiFi.xml b/data_model/master/clusters/DiagnosticsWiFi.xml index b3951d967dc31f..6ef28ee4cc09e0 100644 --- a/data_model/master/clusters/DiagnosticsWiFi.xml +++ b/data_model/master/clusters/DiagnosticsWiFi.xml @@ -55,14 +55,16 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + - + + + @@ -141,81 +143,81 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/data_model/master/clusters/DoorLock.xml b/data_model/master/clusters/DoorLock.xml index ea4b9fe1ebbbf8..138d40bdd544d6 100644 --- a/data_model/master/clusters/DoorLock.xml +++ b/data_model/master/clusters/DoorLock.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - @@ -703,7 +703,7 @@ Davis, CA 95616, USA - + @@ -871,7 +871,7 @@ Davis, CA 95616, USA - + @@ -886,7 +886,7 @@ Davis, CA 95616, USA - + @@ -912,153 +912,156 @@ Davis, CA 95616, USA - + - + - + - + + - + + - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1069,7 +1072,7 @@ Davis, CA 95616, USA - + @@ -1080,7 +1083,7 @@ Davis, CA 95616, USA - + @@ -1092,7 +1095,7 @@ Davis, CA 95616, USA - + @@ -1106,7 +1109,7 @@ Davis, CA 95616, USA - + @@ -1114,12 +1117,12 @@ Davis, CA 95616, USA - + - + @@ -1129,21 +1132,21 @@ Davis, CA 95616, USA - + - + - + @@ -1153,7 +1156,7 @@ Davis, CA 95616, USA - + @@ -1163,14 +1166,14 @@ Davis, CA 95616, USA - + - + @@ -1180,7 +1183,7 @@ Davis, CA 95616, USA - + @@ -1188,7 +1191,7 @@ Davis, CA 95616, USA - + @@ -1196,7 +1199,7 @@ Davis, CA 95616, USA - + @@ -1207,7 +1210,7 @@ Davis, CA 95616, USA - + @@ -1215,7 +1218,7 @@ Davis, CA 95616, USA - + @@ -1226,7 +1229,7 @@ Davis, CA 95616, USA - + @@ -1234,21 +1237,21 @@ Davis, CA 95616, USA - + - + - + @@ -1872,18 +1875,12 @@ Davis, CA 95616, USA - - - - - - + + + + + + @@ -2034,18 +2031,12 @@ Davis, CA 95616, USA - - - - - - + + + + + + diff --git a/data_model/master/clusters/ElectricalEnergyMeasurement.xml b/data_model/master/clusters/ElectricalEnergyMeasurement.xml index d89b19472a6bbb..77e05665b2d031 100644 --- a/data_model/master/clusters/ElectricalEnergyMeasurement.xml +++ b/data_model/master/clusters/ElectricalEnergyMeasurement.xml @@ -124,12 +124,12 @@ Davis, CA 95616, USA - + - + @@ -139,7 +139,7 @@ Davis, CA 95616, USA - + @@ -149,7 +149,7 @@ Davis, CA 95616, USA - + @@ -159,7 +159,7 @@ Davis, CA 95616, USA - + @@ -169,7 +169,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ElectricalPowerMeasurement.xml b/data_model/master/clusters/ElectricalPowerMeasurement.xml index 89ad5fa3255fcd..ba9dd22f3fa799 100644 --- a/data_model/master/clusters/ElectricalPowerMeasurement.xml +++ b/data_model/master/clusters/ElectricalPowerMeasurement.xml @@ -170,39 +170,39 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -210,7 +210,7 @@ Davis, CA 95616, USA - + @@ -218,13 +218,13 @@ Davis, CA 95616, USA - + - + @@ -232,7 +232,7 @@ Davis, CA 95616, USA - + @@ -240,7 +240,7 @@ Davis, CA 95616, USA - + @@ -248,7 +248,7 @@ Davis, CA 95616, USA - + @@ -256,7 +256,7 @@ Davis, CA 95616, USA - + @@ -264,7 +264,7 @@ Davis, CA 95616, USA - + @@ -273,7 +273,7 @@ Davis, CA 95616, USA - + @@ -282,7 +282,7 @@ Davis, CA 95616, USA - + @@ -290,7 +290,7 @@ Davis, CA 95616, USA - + @@ -298,7 +298,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/EnergyCalendar.xml b/data_model/master/clusters/EnergyCalendar.xml index 40a8a87f04ec17..5e9b3b782a435c 100644 --- a/data_model/master/clusters/EnergyCalendar.xml +++ b/data_model/master/clusters/EnergyCalendar.xml @@ -196,17 +196,17 @@ Davis, CA 95616, USA - + - + - + @@ -215,70 +215,70 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/data_model/master/clusters/EnergyEVSE.xml b/data_model/master/clusters/EnergyEVSE.xml index 53605899d05550..e481e06aa4e5d4 100644 --- a/data_model/master/clusters/EnergyEVSE.xml +++ b/data_model/master/clusters/EnergyEVSE.xml @@ -254,7 +254,12 @@ Davis, CA 95616, USA - + + + + + + @@ -262,7 +267,7 @@ Davis, CA 95616, USA - + @@ -275,37 +280,37 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -313,33 +318,33 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -347,14 +352,14 @@ Davis, CA 95616, USA - + - + @@ -362,14 +367,14 @@ Davis, CA 95616, USA - + - + @@ -377,7 +382,7 @@ Davis, CA 95616, USA - + @@ -385,23 +390,23 @@ Davis, CA 95616, USA - + - + - + - + @@ -525,7 +530,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/EnergyPreference.xml b/data_model/master/clusters/EnergyPreference.xml index 37559dfbc30850..cd2b722607a45b 100644 --- a/data_model/master/clusters/EnergyPreference.xml +++ b/data_model/master/clusters/EnergyPreference.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + @@ -102,7 +104,7 @@ Davis, CA 95616, USA - + @@ -110,7 +112,7 @@ Davis, CA 95616, USA - + @@ -118,7 +120,7 @@ Davis, CA 95616, USA - + @@ -127,7 +129,7 @@ Davis, CA 95616, USA - + @@ -135,7 +137,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/EnergyPrice.xml b/data_model/master/clusters/EnergyPrice.xml index fa46810900890f..a4efa28e1b0dbf 100644 --- a/data_model/master/clusters/EnergyPrice.xml +++ b/data_model/master/clusters/EnergyPrice.xml @@ -166,7 +166,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/FanControl.xml b/data_model/master/clusters/FanControl.xml index 12d57967801646..daae13aff910d4 100644 --- a/data_model/master/clusters/FanControl.xml +++ b/data_model/master/clusters/FanControl.xml @@ -120,36 +120,36 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -188,36 +188,36 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -225,7 +225,7 @@ Davis, CA 95616, USA - + @@ -233,7 +233,7 @@ Davis, CA 95616, USA - + @@ -241,7 +241,7 @@ Davis, CA 95616, USA - + @@ -249,7 +249,7 @@ Davis, CA 95616, USA - + @@ -257,7 +257,7 @@ Davis, CA 95616, USA - + @@ -265,7 +265,7 @@ Davis, CA 95616, USA - + @@ -273,7 +273,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/FlowMeasurement.xml b/data_model/master/clusters/FlowMeasurement.xml index d488b5899b05f0..85879977faa509 100644 --- a/data_model/master/clusters/FlowMeasurement.xml +++ b/data_model/master/clusters/FlowMeasurement.xml @@ -70,19 +70,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/master/clusters/GeneralCommissioningCluster.xml b/data_model/master/clusters/GeneralCommissioningCluster.xml index 519285af02f103..ed10afa8406a5a 100644 --- a/data_model/master/clusters/GeneralCommissioningCluster.xml +++ b/data_model/master/clusters/GeneralCommissioningCluster.xml @@ -65,7 +65,7 @@ Davis, CA 95616, USA - + @@ -130,7 +130,7 @@ Davis, CA 95616, USA - + @@ -140,12 +140,12 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/Group-Key-Management-Cluster.xml b/data_model/master/clusters/Group-Key-Management-Cluster.xml index c1819628e34d7b..35de0890bd87d3 100644 --- a/data_model/master/clusters/Group-Key-Management-Cluster.xml +++ b/data_model/master/clusters/Group-Key-Management-Cluster.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - + @@ -167,7 +167,7 @@ Davis, CA 95616, USA - + @@ -179,12 +179,12 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/Groups.xml b/data_model/master/clusters/Groups.xml index 1f168e13fad933..6c53c1a602f255 100644 --- a/data_model/master/clusters/Groups.xml +++ b/data_model/master/clusters/Groups.xml @@ -83,7 +83,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Humidistat.xml b/data_model/master/clusters/Humidistat.xml index b709b5d50d2f24..c3aac1dab85a20 100644 --- a/data_model/master/clusters/Humidistat.xml +++ b/data_model/master/clusters/Humidistat.xml @@ -174,17 +174,17 @@ Davis, CA 95616, USA - + - + - + @@ -192,7 +192,7 @@ Davis, CA 95616, USA - + @@ -200,7 +200,7 @@ Davis, CA 95616, USA - + @@ -208,7 +208,7 @@ Davis, CA 95616, USA - + @@ -228,28 +228,28 @@ Davis, CA 95616, USA - + - + - + - + diff --git a/data_model/master/clusters/ICDManagement.xml b/data_model/master/clusters/ICDManagement.xml index 0f15a2729052fa..d4731fb545ad9a 100644 --- a/data_model/master/clusters/ICDManagement.xml +++ b/data_model/master/clusters/ICDManagement.xml @@ -115,7 +115,7 @@ Davis, CA 95616, USA - + @@ -125,24 +125,24 @@ Davis, CA 95616, USA - + - + - + - + @@ -150,14 +150,14 @@ Davis, CA 95616, USA - + - + @@ -165,7 +165,7 @@ Davis, CA 95616, USA - + @@ -176,7 +176,7 @@ Davis, CA 95616, USA - + @@ -190,7 +190,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Identify.xml b/data_model/master/clusters/Identify.xml index dbb9daca72fce4..0ab68abb8b1635 100644 --- a/data_model/master/clusters/Identify.xml +++ b/data_model/master/clusters/Identify.xml @@ -122,7 +122,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/IlluminanceMeasurement.xml b/data_model/master/clusters/IlluminanceMeasurement.xml index 75cf30cd35d931..f24df314ca2ead 100644 --- a/data_model/master/clusters/IlluminanceMeasurement.xml +++ b/data_model/master/clusters/IlluminanceMeasurement.xml @@ -83,20 +83,20 @@ Davis, CA 95616, USA - + - + - + @@ -107,7 +107,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Label-Cluster-FixedLabelCluster.xml b/data_model/master/clusters/Label-Cluster-FixedLabelCluster.xml index 98106b6fc33e40..b915e77bb5a01f 100644 --- a/data_model/master/clusters/Label-Cluster-FixedLabelCluster.xml +++ b/data_model/master/clusters/Label-Cluster-FixedLabelCluster.xml @@ -70,7 +70,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Label-Cluster-LabelCluster.xml b/data_model/master/clusters/Label-Cluster-LabelCluster.xml index 0ca5566f0dc132..43148b6dc9186f 100644 --- a/data_model/master/clusters/Label-Cluster-LabelCluster.xml +++ b/data_model/master/clusters/Label-Cluster-LabelCluster.xml @@ -80,7 +80,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Label-Cluster-UserLabelCluster.xml b/data_model/master/clusters/Label-Cluster-UserLabelCluster.xml index eba0099ffb59d2..40dac53a4242cd 100644 --- a/data_model/master/clusters/Label-Cluster-UserLabelCluster.xml +++ b/data_model/master/clusters/Label-Cluster-UserLabelCluster.xml @@ -70,7 +70,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/LaundryDryerControls.xml b/data_model/master/clusters/LaundryDryerControls.xml index af4f787c0432b7..d860d2ef9dcf21 100644 --- a/data_model/master/clusters/LaundryDryerControls.xml +++ b/data_model/master/clusters/LaundryDryerControls.xml @@ -88,7 +88,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/LaundryWasherControls.xml b/data_model/master/clusters/LaundryWasherControls.xml index ff001c3a405652..6fbfc0a882d3d1 100644 --- a/data_model/master/clusters/LaundryWasherControls.xml +++ b/data_model/master/clusters/LaundryWasherControls.xml @@ -109,7 +109,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/LevelControl.xml b/data_model/master/clusters/LevelControl.xml index c98db485e6e00a..5da823bc1dceb0 100644 --- a/data_model/master/clusters/LevelControl.xml +++ b/data_model/master/clusters/LevelControl.xml @@ -65,7 +65,9 @@ Davis, CA 95616, USA - + @@ -118,13 +120,13 @@ Davis, CA 95616, USA - + - + @@ -152,7 +154,7 @@ Davis, CA 95616, USA - + @@ -183,28 +185,29 @@ Davis, CA 95616, USA - + - + - + - + + - + diff --git a/data_model/master/clusters/LocalizationConfiguration.xml b/data_model/master/clusters/LocalizationConfiguration.xml index 66809f545389be..7ddfba8efcc9cb 100644 --- a/data_model/master/clusters/LocalizationConfiguration.xml +++ b/data_model/master/clusters/LocalizationConfiguration.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - + @@ -75,7 +75,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/LocalizationTimeFormat.xml b/data_model/master/clusters/LocalizationTimeFormat.xml index db8b809b0341a9..2ede281c7352a9 100644 --- a/data_model/master/clusters/LocalizationTimeFormat.xml +++ b/data_model/master/clusters/LocalizationTimeFormat.xml @@ -125,12 +125,12 @@ Davis, CA 95616, USA - + - + @@ -138,7 +138,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/LocalizationUnit.xml b/data_model/master/clusters/LocalizationUnit.xml index 2c6e1ecbd648e6..0157ebb53b0d39 100644 --- a/data_model/master/clusters/LocalizationUnit.xml +++ b/data_model/master/clusters/LocalizationUnit.xml @@ -84,7 +84,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/MediaPlayback.xml b/data_model/master/clusters/MediaPlayback.xml index 03175277dc12c5..dae60d7a1b2572 100644 --- a/data_model/master/clusters/MediaPlayback.xml +++ b/data_model/master/clusters/MediaPlayback.xml @@ -223,7 +223,7 @@ Davis, CA 95616, USA - + @@ -231,7 +231,7 @@ Davis, CA 95616, USA - + @@ -239,7 +239,7 @@ Davis, CA 95616, USA - + @@ -254,7 +254,7 @@ Davis, CA 95616, USA - + @@ -262,7 +262,7 @@ Davis, CA 95616, USA - + @@ -270,7 +270,7 @@ Davis, CA 95616, USA - + @@ -279,7 +279,7 @@ Davis, CA 95616, USA - + @@ -287,7 +287,7 @@ Davis, CA 95616, USA - + @@ -296,7 +296,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/MicrowaveOvenControl.xml b/data_model/master/clusters/MicrowaveOvenControl.xml index b927685e534e0c..360b9edeaa55f1 100644 --- a/data_model/master/clusters/MicrowaveOvenControl.xml +++ b/data_model/master/clusters/MicrowaveOvenControl.xml @@ -89,7 +89,7 @@ Davis, CA 95616, USA - + @@ -102,7 +102,7 @@ Davis, CA 95616, USA - + @@ -110,7 +110,7 @@ Davis, CA 95616, USA - + @@ -118,7 +118,7 @@ Davis, CA 95616, USA - + @@ -127,7 +127,7 @@ Davis, CA 95616, USA - + @@ -148,7 +148,7 @@ Davis, CA 95616, USA - + @@ -157,21 +157,21 @@ Davis, CA 95616, USA - + - + - + - + diff --git a/data_model/master/clusters/ModeBase.xml b/data_model/master/clusters/ModeBase.xml index 48b4d4adac1634..4a70ad670d0dca 100644 --- a/data_model/master/clusters/ModeBase.xml +++ b/data_model/master/clusters/ModeBase.xml @@ -99,25 +99,25 @@ Davis, CA 95616, USA - + - + - + - + diff --git a/data_model/master/clusters/ModeSelect.xml b/data_model/master/clusters/ModeSelect.xml index cfdf7adb92761c..76ebf5874af273 100644 --- a/data_model/master/clusters/ModeSelect.xml +++ b/data_model/master/clusters/ModeSelect.xml @@ -97,38 +97,38 @@ Davis, CA 95616, USA - + - + - + - + - + - + diff --git a/data_model/master/clusters/Mode_DeviceEnergyManagement.xml b/data_model/master/clusters/Mode_DeviceEnergyManagement.xml index 9cb426eb51785d..08c4044617d716 100644 --- a/data_model/master/clusters/Mode_DeviceEnergyManagement.xml +++ b/data_model/master/clusters/Mode_DeviceEnergyManagement.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/master/clusters/Mode_EVSE.xml b/data_model/master/clusters/Mode_EVSE.xml index ffce1a6a2980ce..f139ab3cbfaf9a 100644 --- a/data_model/master/clusters/Mode_EVSE.xml +++ b/data_model/master/clusters/Mode_EVSE.xml @@ -79,4 +79,23 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/master/clusters/NetworkCommissioningCluster.xml b/data_model/master/clusters/NetworkCommissioningCluster.xml index cb6e935dcd189e..63efd6c3d3cbb2 100644 --- a/data_model/master/clusters/NetworkCommissioningCluster.xml +++ b/data_model/master/clusters/NetworkCommissioningCluster.xml @@ -125,22 +125,22 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -167,16 +167,16 @@ Davis, CA 95616, USA - + - + - + - + @@ -287,7 +287,7 @@ Davis, CA 95616, USA - + @@ -299,7 +299,7 @@ Davis, CA 95616, USA - + @@ -310,7 +310,7 @@ Davis, CA 95616, USA - + @@ -321,29 +321,29 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -351,14 +351,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/NetworkIdentityManagement.xml b/data_model/master/clusters/NetworkIdentityManagement.xml index 0cb3ee17251741..b432b8b68f6b23 100644 --- a/data_model/master/clusters/NetworkIdentityManagement.xml +++ b/data_model/master/clusters/NetworkIdentityManagement.xml @@ -99,26 +99,26 @@ Davis, CA 95616, USA - + - + - + - + diff --git a/data_model/master/clusters/OTARequestor.xml b/data_model/master/clusters/OTARequestor.xml index f6a5ff0365abed..3a562c9f18a046 100644 --- a/data_model/master/clusters/OTARequestor.xml +++ b/data_model/master/clusters/OTARequestor.xml @@ -149,7 +149,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/OccupancySensing.xml b/data_model/master/clusters/OccupancySensing.xml index 2aae8530b1d512..2852ce812f9308 100644 --- a/data_model/master/clusters/OccupancySensing.xml +++ b/data_model/master/clusters/OccupancySensing.xml @@ -63,7 +63,7 @@ Davis, CA 95616, USA - - + - + @@ -164,7 +164,7 @@ Davis, CA 95616, USA - + @@ -178,7 +178,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/OnOff.xml b/data_model/master/clusters/OnOff.xml index a12de2b2e25eb8..b06c96a64376ac 100644 --- a/data_model/master/clusters/OnOff.xml +++ b/data_model/master/clusters/OnOff.xml @@ -145,7 +145,7 @@ Davis, CA 95616, USA - + @@ -168,7 +168,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/OperationalCredentialCluster.xml b/data_model/master/clusters/OperationalCredentialCluster.xml index 2aa070f96b2573..b3811db4a5774a 100644 --- a/data_model/master/clusters/OperationalCredentialCluster.xml +++ b/data_model/master/clusters/OperationalCredentialCluster.xml @@ -155,26 +155,26 @@ Davis, CA 95616, USA - + - + - + - + @@ -183,7 +183,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/OperationalState.xml b/data_model/master/clusters/OperationalState.xml index 124362e459e429..06c77fc29a2c19 100644 --- a/data_model/master/clusters/OperationalState.xml +++ b/data_model/master/clusters/OperationalState.xml @@ -115,19 +115,19 @@ Davis, CA 95616, USA - + - + - + @@ -180,7 +180,6 @@ Davis, CA 95616, USA - diff --git a/data_model/master/clusters/PowerSourceCluster.xml b/data_model/master/clusters/PowerSourceCluster.xml index 1c01cc548bfdee..4596880e32b938 100644 --- a/data_model/master/clusters/PowerSourceCluster.xml +++ b/data_model/master/clusters/PowerSourceCluster.xml @@ -556,32 +556,32 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -589,21 +589,21 @@ Davis, CA 95616, USA - + - + - + @@ -624,14 +624,14 @@ Davis, CA 95616, USA - + - + @@ -639,7 +639,7 @@ Davis, CA 95616, USA - + @@ -659,7 +659,7 @@ Davis, CA 95616, USA - + @@ -680,7 +680,7 @@ Davis, CA 95616, USA - + @@ -688,7 +688,7 @@ Davis, CA 95616, USA - + @@ -696,7 +696,7 @@ Davis, CA 95616, USA - + @@ -704,7 +704,7 @@ Davis, CA 95616, USA - + @@ -712,7 +712,7 @@ Davis, CA 95616, USA - + @@ -720,7 +720,7 @@ Davis, CA 95616, USA - + @@ -730,7 +730,7 @@ Davis, CA 95616, USA - + @@ -744,7 +744,7 @@ Davis, CA 95616, USA - + @@ -757,7 +757,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/PowerSourceConfigurationCluster.xml b/data_model/master/clusters/PowerSourceConfigurationCluster.xml index 6a47ce1b54cdbd..5348f6f0b091b6 100644 --- a/data_model/master/clusters/PowerSourceConfigurationCluster.xml +++ b/data_model/master/clusters/PowerSourceConfigurationCluster.xml @@ -67,7 +67,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/PowerTopology.xml b/data_model/master/clusters/PowerTopology.xml index 4ebdda614a4aec..b958d03c01aeb1 100644 --- a/data_model/master/clusters/PowerTopology.xml +++ b/data_model/master/clusters/PowerTopology.xml @@ -83,7 +83,7 @@ Davis, CA 95616, USA - + @@ -92,7 +92,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/PressureMeasurement.xml b/data_model/master/clusters/PressureMeasurement.xml index a46e911253941f..bf9b6a9286e381 100644 --- a/data_model/master/clusters/PressureMeasurement.xml +++ b/data_model/master/clusters/PressureMeasurement.xml @@ -75,19 +75,19 @@ Davis, CA 95616, USA - + - + - + @@ -98,7 +98,7 @@ Davis, CA 95616, USA - + @@ -106,7 +106,7 @@ Davis, CA 95616, USA - + @@ -114,7 +114,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ProxyConfiguration-Cluster.xml b/data_model/master/clusters/ProxyConfiguration-Cluster.xml index 8ad566ec8527b2..c33ed5cd03b841 100644 --- a/data_model/master/clusters/ProxyConfiguration-Cluster.xml +++ b/data_model/master/clusters/ProxyConfiguration-Cluster.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + @@ -82,7 +84,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ProxyDiscovery-Cluster.xml b/data_model/master/clusters/ProxyDiscovery-Cluster.xml index 6fa4a9eb6f3a06..159bdff7333853 100644 --- a/data_model/master/clusters/ProxyDiscovery-Cluster.xml +++ b/data_model/master/clusters/ProxyDiscovery-Cluster.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/master/clusters/PumpConfigurationControl.xml b/data_model/master/clusters/PumpConfigurationControl.xml index c3f79ce8108975..95ede00d0eb72e 100644 --- a/data_model/master/clusters/PumpConfigurationControl.xml +++ b/data_model/master/clusters/PumpConfigurationControl.xml @@ -176,22 +176,22 @@ Davis, CA 95616, USA - + - + - + - + @@ -203,7 +203,7 @@ Davis, CA 95616, USA - + @@ -215,7 +215,7 @@ Davis, CA 95616, USA - + @@ -227,7 +227,7 @@ Davis, CA 95616, USA - + @@ -239,7 +239,7 @@ Davis, CA 95616, USA - + @@ -251,7 +251,7 @@ Davis, CA 95616, USA - + @@ -263,7 +263,7 @@ Davis, CA 95616, USA - + @@ -275,7 +275,7 @@ Davis, CA 95616, USA - + @@ -287,7 +287,7 @@ Davis, CA 95616, USA - + @@ -300,7 +300,7 @@ Davis, CA 95616, USA - + @@ -313,62 +313,62 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + diff --git a/data_model/master/clusters/ResourceMonitoring.xml b/data_model/master/clusters/ResourceMonitoring.xml index 43bf28868f3709..feb6394fd6b47d 100644 --- a/data_model/master/clusters/ResourceMonitoring.xml +++ b/data_model/master/clusters/ResourceMonitoring.xml @@ -62,9 +62,9 @@ Davis, CA 95616, USA - - - + + + @@ -74,7 +74,7 @@ Davis, CA 95616, USA - + @@ -104,13 +104,13 @@ Davis, CA 95616, USA - + - + @@ -137,7 +137,7 @@ Davis, CA 95616, USA - + @@ -153,13 +153,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/Scenes.xml b/data_model/master/clusters/Scenes.xml index bf68f8528fa159..1479d3ffd7de86 100644 --- a/data_model/master/clusters/Scenes.xml +++ b/data_model/master/clusters/Scenes.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + @@ -165,12 +167,12 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/ServiceArea.xml b/data_model/master/clusters/ServiceArea.xml index 7963d93b7eb222..4980fc5ad40274 100644 --- a/data_model/master/clusters/ServiceArea.xml +++ b/data_model/master/clusters/ServiceArea.xml @@ -86,6 +86,34 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -152,26 +180,26 @@ Davis, CA 95616, USA - + - + - + - + @@ -179,7 +207,7 @@ Davis, CA 95616, USA - + @@ -196,7 +224,6 @@ Davis, CA 95616, USA - @@ -215,7 +242,6 @@ Davis, CA 95616, USA - diff --git a/data_model/master/clusters/SmokeCOAlarm.xml b/data_model/master/clusters/SmokeCOAlarm.xml index 25c034ac94082c..4ba9bd2708b476 100644 --- a/data_model/master/clusters/SmokeCOAlarm.xml +++ b/data_model/master/clusters/SmokeCOAlarm.xml @@ -163,31 +163,31 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -196,12 +196,12 @@ Davis, CA 95616, USA - + - + @@ -226,7 +226,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Switch.xml b/data_model/master/clusters/Switch.xml index c7c94524bed52c..bb2066269b4f94 100644 --- a/data_model/master/clusters/Switch.xml +++ b/data_model/master/clusters/Switch.xml @@ -116,19 +116,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/master/clusters/TemperatureControl.xml b/data_model/master/clusters/TemperatureControl.xml index 3f5fa9c00332d6..2f2527ce4ad0fa 100644 --- a/data_model/master/clusters/TemperatureControl.xml +++ b/data_model/master/clusters/TemperatureControl.xml @@ -86,7 +86,7 @@ Davis, CA 95616, USA - + @@ -94,7 +94,7 @@ Davis, CA 95616, USA - + @@ -102,7 +102,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/TemperatureMeasurement.xml b/data_model/master/clusters/TemperatureMeasurement.xml index 176fad6b246a60..0935b18edab675 100644 --- a/data_model/master/clusters/TemperatureMeasurement.xml +++ b/data_model/master/clusters/TemperatureMeasurement.xml @@ -71,19 +71,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/master/clusters/Thermostat.xml b/data_model/master/clusters/Thermostat.xml index 7345fc2e2c9177..4374bc3f1c8a7d 100644 --- a/data_model/master/clusters/Thermostat.xml +++ b/data_model/master/clusters/Thermostat.xml @@ -113,11 +113,6 @@ Davis, CA 95616, USA - - - - - @@ -503,12 +498,12 @@ Davis, CA 95616, USA - + - + @@ -559,15 +554,6 @@ Davis, CA 95616, USA - - - - - - - - - @@ -660,12 +646,12 @@ Davis, CA 95616, USA - + - + @@ -677,7 +663,7 @@ Davis, CA 95616, USA - + @@ -685,7 +671,7 @@ Davis, CA 95616, USA - + @@ -693,7 +679,7 @@ Davis, CA 95616, USA - + @@ -701,7 +687,7 @@ Davis, CA 95616, USA - + @@ -709,7 +695,7 @@ Davis, CA 95616, USA - + @@ -717,7 +703,7 @@ Davis, CA 95616, USA - + @@ -725,13 +711,13 @@ Davis, CA 95616, USA - + - + @@ -740,7 +726,7 @@ Davis, CA 95616, USA - + @@ -748,7 +734,7 @@ Davis, CA 95616, USA - + @@ -756,7 +742,7 @@ Davis, CA 95616, USA - + @@ -767,7 +753,7 @@ Davis, CA 95616, USA - + @@ -778,7 +764,7 @@ Davis, CA 95616, USA - + @@ -786,7 +772,7 @@ Davis, CA 95616, USA - + @@ -794,7 +780,7 @@ Davis, CA 95616, USA - + @@ -802,7 +788,7 @@ Davis, CA 95616, USA - + @@ -810,7 +796,7 @@ Davis, CA 95616, USA - + @@ -818,19 +804,19 @@ Davis, CA 95616, USA - + - + - + @@ -850,7 +836,7 @@ Davis, CA 95616, USA - + @@ -858,33 +844,33 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -900,7 +886,7 @@ Davis, CA 95616, USA - + @@ -909,7 +895,7 @@ Davis, CA 95616, USA - + @@ -917,7 +903,7 @@ Davis, CA 95616, USA - + @@ -925,7 +911,7 @@ Davis, CA 95616, USA - + @@ -933,7 +919,7 @@ Davis, CA 95616, USA - + @@ -944,7 +930,7 @@ Davis, CA 95616, USA - + @@ -955,7 +941,7 @@ Davis, CA 95616, USA - + @@ -966,29 +952,29 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -998,25 +984,25 @@ Davis, CA 95616, USA - + - + - + - + @@ -1025,7 +1011,7 @@ Davis, CA 95616, USA - + @@ -1033,35 +1019,35 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -1069,7 +1055,7 @@ Davis, CA 95616, USA - + @@ -1078,7 +1064,7 @@ Davis, CA 95616, USA - + @@ -1087,7 +1073,7 @@ Davis, CA 95616, USA - + @@ -1104,16 +1090,9 @@ Davis, CA 95616, USA - + - - - - - - - @@ -1243,11 +1222,6 @@ Davis, CA 95616, USA - - - - - @@ -1280,11 +1254,5 @@ Davis, CA 95616, USA - - - - - - \ No newline at end of file diff --git a/data_model/master/clusters/ThreadBorderRouterManagement.xml b/data_model/master/clusters/ThreadBorderRouterManagement.xml index f1e88f8ab86e70..b22d4038219647 100644 --- a/data_model/master/clusters/ThreadBorderRouterManagement.xml +++ b/data_model/master/clusters/ThreadBorderRouterManagement.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - + @@ -79,20 +79,26 @@ Davis, CA 95616, USA + - + - + - + + + + + + @@ -105,14 +111,14 @@ Davis, CA 95616, USA - + - + @@ -123,7 +129,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ThreadNetworkDirectory.xml b/data_model/master/clusters/ThreadNetworkDirectory.xml index 3a770c36a214f9..aeabdcf19f93d1 100644 --- a/data_model/master/clusters/ThreadNetworkDirectory.xml +++ b/data_model/master/clusters/ThreadNetworkDirectory.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - + @@ -74,7 +74,7 @@ Davis, CA 95616, USA - + @@ -82,19 +82,19 @@ Davis, CA 95616, USA - + - + - + - + diff --git a/data_model/master/clusters/TimeSync.xml b/data_model/master/clusters/TimeSync.xml index 9d4057db8bdb85..a506a647aeb8a3 100644 --- a/data_model/master/clusters/TimeSync.xml +++ b/data_model/master/clusters/TimeSync.xml @@ -213,7 +213,7 @@ Davis, CA 95616, USA - + @@ -228,14 +228,14 @@ Davis, CA 95616, USA - + - + @@ -244,7 +244,7 @@ Davis, CA 95616, USA - + @@ -253,21 +253,21 @@ Davis, CA 95616, USA - + - + - + @@ -280,7 +280,7 @@ Davis, CA 95616, USA - + @@ -288,7 +288,7 @@ Davis, CA 95616, USA - + @@ -296,7 +296,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ValidProxies-Cluster.xml b/data_model/master/clusters/ValidProxies-Cluster.xml index b9db8e1762647f..c5740c90e52433 100644 --- a/data_model/master/clusters/ValidProxies-Cluster.xml +++ b/data_model/master/clusters/ValidProxies-Cluster.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + @@ -75,7 +77,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ValveConfigurationControl.xml b/data_model/master/clusters/ValveConfigurationControl.xml index e8dcece07432d3..736672bc78f716 100644 --- a/data_model/master/clusters/ValveConfigurationControl.xml +++ b/data_model/master/clusters/ValveConfigurationControl.xml @@ -109,55 +109,55 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + @@ -169,7 +169,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/WakeOnLAN.xml b/data_model/master/clusters/WakeOnLAN.xml index 4f6e032c084b38..7f5c08bdd624ad 100644 --- a/data_model/master/clusters/WakeOnLAN.xml +++ b/data_model/master/clusters/WakeOnLAN.xml @@ -68,13 +68,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/WaterContentMeasurement.xml b/data_model/master/clusters/WaterContentMeasurement.xml index 85d44793c93ae4..af11c9cf8d514c 100644 --- a/data_model/master/clusters/WaterContentMeasurement.xml +++ b/data_model/master/clusters/WaterContentMeasurement.xml @@ -70,19 +70,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/master/clusters/WaterHeaterManagement.xml b/data_model/master/clusters/WaterHeaterManagement.xml index 52e1020f164472..ee38a0058b50fb 100644 --- a/data_model/master/clusters/WaterHeaterManagement.xml +++ b/data_model/master/clusters/WaterHeaterManagement.xml @@ -74,6 +74,14 @@ Davis, CA 95616, USA + + + + + + + + @@ -112,7 +120,7 @@ Davis, CA 95616, USA - + @@ -137,7 +145,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/WiFiNetworkManagement.xml b/data_model/master/clusters/WiFiNetworkManagement.xml index e1c03fbc7061d4..cfa10af25f0dd6 100644 --- a/data_model/master/clusters/WiFiNetworkManagement.xml +++ b/data_model/master/clusters/WiFiNetworkManagement.xml @@ -57,18 +57,18 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + - + - + diff --git a/data_model/master/clusters/WindowCovering.xml b/data_model/master/clusters/WindowCovering.xml index 7ec63dd442d8ae..2f087914405cf3 100644 --- a/data_model/master/clusters/WindowCovering.xml +++ b/data_model/master/clusters/WindowCovering.xml @@ -392,13 +392,13 @@ Davis, CA 95616, USA - + - + @@ -409,7 +409,7 @@ Davis, CA 95616, USA - + @@ -420,7 +420,7 @@ Davis, CA 95616, USA - + @@ -432,7 +432,7 @@ Davis, CA 95616, USA - + @@ -444,27 +444,27 @@ Davis, CA 95616, USA - + - + - + - + @@ -474,7 +474,7 @@ Davis, CA 95616, USA - + @@ -485,13 +485,13 @@ Davis, CA 95616, USA - + - + @@ -501,7 +501,7 @@ Davis, CA 95616, USA - + @@ -511,13 +511,13 @@ Davis, CA 95616, USA - + - + @@ -528,7 +528,7 @@ Davis, CA 95616, USA - + @@ -539,7 +539,7 @@ Davis, CA 95616, USA - + @@ -551,7 +551,7 @@ Davis, CA 95616, USA - + @@ -563,7 +563,7 @@ Davis, CA 95616, USA - + @@ -575,7 +575,7 @@ Davis, CA 95616, USA - + @@ -596,7 +596,7 @@ Davis, CA 95616, USA - + @@ -608,7 +608,7 @@ Davis, CA 95616, USA - + @@ -653,11 +653,11 @@ Davis, CA 95616, USA - + - + @@ -688,11 +688,11 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml b/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml index 42ae5c4fe44cee..4801cbf88800ae 100644 --- a/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml +++ b/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml @@ -115,20 +115,20 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/master/clusters/cluster_ids.json b/data_model/master/clusters/cluster_ids.json index c7654179ede2b5..e04a90b04a76d8 100644 --- a/data_model/master/clusters/cluster_ids.json +++ b/data_model/master/clusters/cluster_ids.json @@ -21,7 +21,7 @@ "51": "General Diagnostics", "52": "Software Diagnostics", "53": "Thread Network Diagnostics", - "54": "Wi", + "54": "Wi-Fi Network Diagnostics", "55": "Ethernet Network Diagnostics", "56": "Time Synchronization", "57": "Bridged Device Basic Information", @@ -95,14 +95,14 @@ "1037": "Carbon Dioxide Concentration Measurement", "1043": "Nitrogen Dioxide Concentration Measurement", "1045": "Ozone Concentration Measurement", - "1066": "PM2", + "1066": "PM2.5 Concentration Measurement", "1067": "Formaldehyde Concentration Measurement", "1068": "PM1 Concentration Measurement", "1069": "PM10 Concentration Measurement", "1070": "Total Volatile Organic Compounds Concentration Measurement", "1071": "Radon Concentration Measurement", "1104": "Network Identity Management", - "1105": "Wi", + "1105": "Wi-Fi Network Management", "1106": "Thread Border Router Management", "1107": "Thread Network Directory", "1283": "Wake on LAN", diff --git a/data_model/master/device_types/AirQualitySensor.xml b/data_model/master/device_types/AirQualitySensor.xml index 602781819d1696..bf56eb754f24c6 100644 --- a/data_model/master/device_types/AirQualitySensor.xml +++ b/data_model/master/device_types/AirQualitySensor.xml @@ -86,7 +86,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/device_types/DimmablePlug-InUnit.xml b/data_model/master/device_types/DimmablePlug-InUnit.xml index 4d344bfc9fb89c..65f6b6e1dd2e9c 100644 --- a/data_model/master/device_types/DimmablePlug-InUnit.xml +++ b/data_model/master/device_types/DimmablePlug-InUnit.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/NetworkInfraManager.xml b/data_model/master/device_types/NetworkInfraManager.xml index 800ca8ce10ace6..a4d17e11c0faaa 100644 --- a/data_model/master/device_types/NetworkInfraManager.xml +++ b/data_model/master/device_types/NetworkInfraManager.xml @@ -62,7 +62,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/device_types/OnOffPlug-inUnit.xml b/data_model/master/device_types/OnOffPlug-inUnit.xml index 3be1ed0f9eb13d..888f365bed0b83 100644 --- a/data_model/master/device_types/OnOffPlug-inUnit.xml +++ b/data_model/master/device_types/OnOffPlug-inUnit.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/RootNodeDeviceType.xml b/data_model/master/device_types/RootNodeDeviceType.xml index 875a633f9ba9b8..7dfd31996cc8e5 100644 --- a/data_model/master/device_types/RootNodeDeviceType.xml +++ b/data_model/master/device_types/RootNodeDeviceType.xml @@ -123,7 +123,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/device_types/SecondaryNetworkInterface.xml b/data_model/master/device_types/SecondaryNetworkInterface.xml index 186faac2718079..51b4dc0e2ec4fa 100644 --- a/data_model/master/device_types/SecondaryNetworkInterface.xml +++ b/data_model/master/device_types/SecondaryNetworkInterface.xml @@ -69,7 +69,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/scraper_version b/data_model/master/scraper_version index e8ea05db81420d..c813fe116c9f9e 100644 --- a/data_model/master/scraper_version +++ b/data_model/master/scraper_version @@ -1 +1 @@ -1.2.4 +1.2.5 diff --git a/data_model/master/spec_sha b/data_model/master/spec_sha index f0b38ddc8c8aac..51aac4d9e877f4 100644 --- a/data_model/master/spec_sha +++ b/data_model/master/spec_sha @@ -1 +1 @@ -b3652909bdf595c7634cea1da0f1e58f837ea35f +358a64a52ea9583f19be23c7da0e33f19d4b1ee0 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/esp32/providers.md b/docs/guides/esp32/providers.md index 5174e1ccaceb11..59b91b624a49fc 100644 --- a/docs/guides/esp32/providers.md +++ b/docs/guides/esp32/providers.md @@ -15,6 +15,8 @@ Below are the providers that have been implemented: - [Device Info Provider](https://github.com/project-chip/connectedhomeip/blob/master/src/platform/ESP32/ESP32DeviceInfoProvider.h#L31) This provider provides fixed labels, supported calendar types, and supported locales from the factory partition. +- [Supported Modes](https://github.com/project-chip/connectedhomeip/blob/master/examples/platform/esp32/mode-support/static-supported-modes-manager.h#L28) + This provider offers the supported modes for the mode-select cluster. More information can be found in the [factory data guide](factory_data.md). 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/spec_clusters.md b/docs/spec_clusters.md index 976b9f85e42c19..ef58f016154446 100644 --- a/docs/spec_clusters.md +++ b/docs/spec_clusters.md @@ -26,7 +26,7 @@ This file was **AUTOMATICALLY** generated by `python scripts/generate_spec_xml.p |51 |0x0033 |General Diagnostics | |52 |0x0034 |Software Diagnostics | |53 |0x0035 |Thread Network Diagnostics | -|54 |0x0036 |Wi | +|54 |0x0036 |Wi-Fi Network Diagnostics | |55 |0x0037 |Ethernet Network Diagnostics | |56 |0x0038 |Time Synchronization | |57 |0x0039 |Bridged Device Basic Information | @@ -92,7 +92,7 @@ This file was **AUTOMATICALLY** generated by `python scripts/generate_spec_xml.p |1037 |0x040D |Carbon Dioxide Concentration Measurement | |1043 |0x0413 |Nitrogen Dioxide Concentration Measurement | |1045 |0x0415 |Ozone Concentration Measurement | -|1066 |0x042A |PM2 | +|1066 |0x042A |PM2.5 Concentration Measurement | |1067 |0x042B |Formaldehyde Concentration Measurement | |1068 |0x042C |PM1 Concentration Measurement | |1069 |0x042D |PM10 Concentration Measurement | diff --git a/docs/testing/python.md b/docs/testing/python.md index 06051fee4fb33b..354490c896c445 100644 --- a/docs/testing/python.md +++ b/docs/testing/python.md @@ -24,33 +24,39 @@ Python tests located in src/python_testing essential to define arguments at the top of the test script. This section should include various parameters and their respective values, which will guide the test runner on how to execute the tests. -- All test classes inherit from MatterBaseTest in +- All test classes inherit from `MatterBaseTest` in [matter_testing_support.py](https://github.com/project-chip/connectedhomeip/blob/master/src/python_testing/matter_testing_support.py) - - support for commissioning using the python controller - - default controller (self.default_controller) of type ChipDeviceCtrl - - MatterBaseTest inherits from the Mobly BaseTestClass -- Test function(s) (start with test\_) and are all run automatically - - To run in the test harness, the test name must be test_TC_PICSCODE\_#\_# - - more information about integration with the test harness can be + - Support for commissioning using the python controller + - Default controller (`self.default_controller`) of type `ChipDeviceCtrl` + - `MatterBaseTest` inherits from the Mobly BaseTestClass +- Test method(s) (start with test\_) and are all run automatically + - To run in the test harness, the test method name must be + `test_TC_PICSCODE_#_#` + - More information about integration with the test harness can be found in [Test Harness helpers](#test-harness-helpers) section - - any tests that use async function (read / write / commands) should be + - Any tests that use async method (read / write / commands) should be decorated with the @async_test_body decorator -- Use ChipDeviceCtrl to interact with the DUT - - Controller API is in ChipDeviceCtrl.py (see API doc in file) - - some support functions in matter_testing_support.py +- Use `ChipDeviceCtrl` to interact with the DUT + - Controller API is in `ChipDeviceCtrl.py` (see API doc in file) + - Some support methods in `matter_testing_support.py` - Use Mobly assertions for failing tests -- self.step() along with a steps\_ function to mark test plan steps for cert +- `self.step()` along with a `steps_*` method to mark test plan steps for cert tests ### A simple test ``` +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === class TC_MYTEST_1_1(MatterBaseTest): @@ -74,69 +80,19 @@ default_matter_test_main() --- -In this test, asserts.assert_equal is used to fail the test on condition failure -(throws an exception). +In this test, `asserts.assert_equal` is used to fail the test on equality +assertion failure (throws an exception). -Because the test requires the use of the async function -read_single_attribute_check_success, the test is decorated with the +Because the test requires the use of the async method +`read_single_attribute_check_success`, the test is decorated with the `@async_test_body` decorator -The default_matter_test_main() function is used to run the test on the command +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 @@ -156,12 +112,12 @@ always: Each `Clusters.` will include the appropriate sub-classes (if defined for the cluster): -- Enums -- Bitmaps -- Structs -- Attributes -- Commands -- Events +- `Enums` +- `Bitmaps` +- `Structs` +- `Attributes` +- `Commands` +- `Events` ### Attributes @@ -176,42 +132,41 @@ Each `Clusters..Attributes.` class has: Example: -- class - Clusters.OnOff.Attributes.OnTime - - used for Read commands -- instance - Clusters.OnOff.Attributes.OnTime(5) - - sets the value to 5 - - pass the instance to write commands to write the value +- class - `Clusters.OnOff.Attributes.OnTime` + - Used for Read commands +- instance - `Clusters.OnOff.Attributes.OnTime(5)` + - Sets the value to `5` + - Pass the instance to Write method to write the value ### Commands -Commands derive from ClusterCommand +Commands derive from `ClusterCommand`. Each `Clusters..Commands.` class has: -- cluster_id -- command_id -- is_client -- response_type (None for status response) -- descriptor +- `cluster_id` +- `command_id` +- `is_client` +- `response_type` (None for status response) +- `descriptor` - data members (if required) Example: -- Clusters.OnOff.Commands.OnWithTimedOff(onOffControl=0, onTime=5, - offWaitTime=8) -- Clusters.OnOff.Commands.OnWithTimedOff() - - command with no fields +- `Clusters.OnOff.Commands.OnWithTimedOff(onOffControl=0, onTime=5, offWaitTime=8)` +- `Clusters.OnOff.Commands.OnWithTimedOff()` + - Command with no fields ### Events -Events derive from ClusterEvent +Events derive from `ClusterEvent`. Each `Clusters..Events.` class has: -- cluster_id -- event_id -- descriptor -- data members if required +- `cluster_id` +- `event_id` +- `descriptor` +- Other data members if required Example: @@ -219,16 +174,16 @@ Example: ### Enums -Enums derive from MatterIntEnum +Enums derive from `MatterIntEnum`. Each `Clusters..Enum.` has -- k -- kUnknownEnumValue (used for testing, do not transmit) +- `k` constants +- `kUnknownEnumValue` (used for testing, do not transmit) Example: -- Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kAdminister +- `Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kAdminister` ### Bitmaps @@ -238,26 +193,28 @@ Each `Clusters..Bitmaps.` has: - k Special class: -- class Feature(IntFlag) - contains the feature map bitmaps +- class `Feature(IntFlag)` - contains the feature map bitmaps Example: -- Clusters.LaundryWasherControls.Bitmaps.Feature.kSpin +- `Clusters.LaundryWasherControls.Bitmaps.Feature.kSpin` ### Structs -Structs derive from ClusterObject +Structs derive from `ClusterObject`. Each `Clusters..Structs.` has: -- descriptor -- data members +- A "descriptor" +- Data members -Example +Example: -- Clusters.BasicInformation.Structs.ProductAppearanceStruct( -- finish=Clusters.BasicInformation.Enums.ProductFinishEnum.kFabric, -- primaryColor=Clusters.BasicInformation.Enums.ColorEnum.kBlack) +``` +Clusters.BasicInformation.Structs.ProductAppearanceStruct( + finish=Clusters.BasicInformation.Enums.ProductFinishEnum.kFabric, + primaryColor=Clusters.BasicInformation.Enums.ColorEnum.kBlack) +``` ## Accessing Clusters and Cluster Elements by ID @@ -266,14 +223,14 @@ has a set of objects that map ID to the code generated object. `chip.clusters.ClusterObjects.ALL_CLUSTERS` -- dict[int, Cluster] - maps cluster ID to Cluster class -- cluster = chip.clusters.ClusterObjects.ALL_CLUSTERS[cluster_id] +- `dict[int, Cluster]` - maps cluster ID to Cluster class + - `cluster = chip.clusters.ClusterObjects.ALL_CLUSTERS[cluster_id]` `chip.clusters.ClusterObjects.ALL_ATTRIBUTES` -- dict[int, dict[int, ClusterAttributeDescriptor]] - maps cluster ID to a dict - of attribute ID to attribute class -- attr = chip.clusters.ClusterObjects.ALL_ATTRIBUTES[cluster_id][attribute_id] +- `dict[int, dict[int, ClusterAttributeDescriptor]]` - maps cluster ID to a + dict of attribute ID to attribute class + - `attr = chip.clusters.ClusterObjects.ALL_ATTRIBUTES[cluster_id][attribute_id]` `chip.clusters.ClusterObjects.ALL_ACCEPTED_COMMANDS/ALL_GENERATED_COMMANDS` @@ -282,15 +239,15 @@ has a set of objects that map ID to the code generated object. ## ChipDeviceCtrl API -The ChipDeviceCtrl API is implemented in +The `ChipDeviceCtrl` API is implemented in [ChipDeviceCtrl.py](https://github.com/project-chip/connectedhomeip/blob/master/src/controller/python/chip/ChipDeviceCtrl.py). -The ChipDeviceCtrl implements a python-based controller that can be used to +The `ChipDeviceCtrl` implements a python-based controller that can be used to commission and control devices. The API is documented here in the [ChipDeviceCtrl API documentation](./ChipDeviceCtrlAPI.md) The API doc gives full descriptions of the APIs being used. The most commonly -used functions are linked below +used methods are linked below. ### [Read](./ChipDeviceCtrlAPI.md#read) @@ -299,7 +256,7 @@ used functions are linked below ### [ReadAttribute](./ChipDeviceCtrlAPI.md#readattribute) -- convenience wrapper for Read for attributes +- Convenience wrapper for Read for attributes Examples: Wildcard read (all clusters, all endpoints): @@ -323,8 +280,9 @@ Multi-path ### [ReadEvent](./ChipDeviceCtrlAPI.md#readevent) -- convenience wrapper for Read -- Similar to ReadAttribute, but the tuple includes urgency as the last number +- Convenience wrapper for `Read` +- Similar to `ReadAttribute`, but the tuple includes urgency as the last + argument Example: @@ -337,19 +295,19 @@ Clusters.TimeSynchronization.Events.MissingTrustedTimeSource, urgent)]) ### Subscriptions -Subscriptions are handled in the Read / ReadAttribute / ReadEvent APIs. To -initiate a subscription, set the `reportInterval` tuple to set the floor and -ceiling. The `keepSubscriptions` and `autoResubscribe` parameters also apply to -subscriptions. +Subscriptions are handled in the `Read` / `ReadAttribute` / `ReadEvent` APIs. To +initiate a subscription, set the `reportInterval` tuple argument to set the +floor and ceiling. The `keepSubscriptions` and `autoResubscribe` arguments also +apply to subscriptions. Subscription return `ClusterAttribute.SubscriptionTransaction`. This can be used to set callbacks. The object is returned after the priming data read is complete, and the values there are used to populate the cache. The attribute callbacks are called on update. -- SetAttributeUpdateCallback +- `SetAttributeUpdateCallback` - Callable[[TypedAttributePath, SubscriptionTransaction], None] -- SetEventUpdateCallback +- `SetEventUpdateCallback` - Callable[[EventReadResult, SubscriptionTransaction], None] - await changes in the main loop using a trigger mechanism from the callback. @@ -387,7 +345,7 @@ asserts.assert_equal(ret[0].status, Status.Success, “write failed”) ### [SendCommand](./ChipDeviceCtrlAPI.md#sendcommand) -- Instantiate the command with the values you need to populate +- Instantiate the command object with the values you need to populate - If there is a non-status return, it’s returned from the command - If there is a pure status return it will return nothing - Raises InteractionModelError on failure @@ -403,62 +361,63 @@ pai = await dev_ctrl.SendCommand(nodeid, 0, Clusters.OperationalCredentials.Comm - Because we tend to do a lot of single read / single commands in tests, we added a couple of helpers in MatterBaseTest that use some of the default values - - read_single_attribute_check_success - - read_single_attribute_expect_error - - send_single_cmd -- step() function to mark step progress for the test harness -- skip / skip_step / skip_remaining_steps functions for test harness + - `read_single_attribute_check_success()` + - `read_single_attribute_expect_error()` + - `send_single_cmd()` +- `step()` method to mark step progress for the test harness +- `skip()` / `skip_step()` / `skip_remaining_steps()` methods for test harness integration -- check_pics / pics_guard to handle pics +- `check_pics()` / `pics_guard()` to handle pics ## Mobly helpers The test system is based on Mobly, and the [matter_testing_support.py](https://github.com/project-chip/connectedhomeip/blob/master/src/python_testing/matter_testing_support.py) -class provides some helpers for Mobly integration +class provides some helpers for Mobly integration. -- default_matter_test_main - - Sets up commissioning and finds all tests, parses command arguments +- `default_matter_test_main` + - Sets up commissioning and finds all tests, parses command-line arguments use as: ``` if __name__ == "__main__": -default_matter_test_main() + default_matter_test_main() ``` -- Mobly will run all functions starting with test\_ by default - - use --tests command line argument to specify -- Setup / teardown functions - - setup_class / teardown_class - - setup_test / teardown_test - - Don’t forget to call the super() if you override these +- Mobly will run all methods starting with `test_` prefix by default + - use `--tests` command line argument to specify exact name,s +- Setup and teardown methods + - `setup_class` / `teardown_class` + - `setup_test` / `teardown_test` + - Don’t forget to call the `super()` if you override these ## Test harness helpers -The python testing system also includes several functions for integrations with +The python testing system also includes several methods for integrations with the test harness. To integrate with the test harness, you can define the -following functions on your class to allow the test harness UI to properly work +following methods on your class to allow the test harness UI to properly work through your tests. -All of these functions are demonstrated in the +All of these methods are demonstrated in the [hello_example.py](https://github.com/project-chip/connectedhomeip/blob/master/src/python_testing/hello_test.py) reference. -- step enumeration - - define a function called `steps_YourFunctionName` to allow the test +- Steps enumeration: + - Define a method called `steps_` to allow the test harness to display the steps - - use the self.step(``) function to walk through the steps -- test description - - define a function called `desc_YourFunctionName` to send back a string + - Use the `self.step()` method to walk through the steps +- Test description: + - Define a method called `desc_` to send back a string with the test description -- top level PICS - - To guard your test on a top level PICS, define a function called - `pics_YourFunctionName` to send back a list of pics. If this function is - omitted, the test will be run for every endpoint on every device. -- overriding the default timeout - - if the test is exceptionally long running, define a property function - `default_timeout` to adjust the timeout. The default is 90 seconds +- Top-level PICS: + - To guard your test on a top level PICS, define a method called + `pics_` to send back a list of PICS. If this method + is omitted, the test will be run for every endpoint on every device. +- Overriding the default timeout: + - If the test is exceptionally long running, define a property getter + method `default_timeout` to adjust the timeout. The default is 90 + seconds. Deferred failures: For some tests, it makes sense to perform the entire test before failing and collect all the errors so the developers can address all the @@ -466,13 +425,13 @@ failures without needing to re-run the test multiple times. For example, tests that look at every attribute on the cluster and perform independent operations on them etc. -For such tests, use the ProblemNotice format and the convenience functions: +For such tests, use the ProblemNotice format and the convenience methods: -- self.record_error -- self.record_warning +- `self.record_error` +- `self.record_warning` -These functions keep track of the problems, and will print them at the end of -the test. The test will not be failed until the assert is called. +These methods keep track of the problems, and will print them at the end of the +test. The test will not be failed until an assert is called. A good example of this type of test can be found in the device basic composition tests, where all the test steps are independent and performed on a single read. @@ -481,16 +440,21 @@ See ## Command line arguments -- Use help to get a full list -- --commissioning-method - - need to re-commission to python controller as chip-tool and python +- Use `--help` to get a full list +- `--storage-path` + - Used to set a local storage file path for persisted data to avoid + clashing files. It is suggested to always provide this argument. Default + value is `admin_storage.json` in current directory. +- `--commissioning-method` + - Need to re-commission to python controller as chip-tool and python commissioner do not share a credentials -- --discriminator, --passcode, --qr-code, --manual-code -- --tests to select tests -- --PICS -- --int-arg, --bool-arg, --float-arg, --string-arg, --json-arg, --hex-arg - - specify as key:value ex --bool-arg pixit_name:False - - used for custom arguments to scripts (PIXITs) +- `--discriminator`, `--passcode`, `--qr-code`, `--manual-code` +- `--tests` to select tests +- `--PICS` +- `--int-arg`, `--bool-arg`, `--float-arg`, `--string-arg`, `--json-arg`, + `--hex-arg` + - Specify as key:value ex --bool-arg pixit_name:False + - Used for custom arguments to scripts (PIXITs) ## PICS and PIXITS @@ -504,7 +468,7 @@ See comments - pixit_value = self.user_params.get("pixit_name", default) -## Support functions +## Support functionality To create a controller on a new fabric: @@ -512,7 +476,7 @@ To create a controller on a new fabric: new_CA = self.certificate_authority_manager.NewCertificateAuthority() new_fabric_admin = new_certificate_authority.NewFabricAdmin(vendorId=0xFFF1, -fabricId=self.matter_test_config.fabric_id + 1) + fabricId=self.matter_test_config.fabric_id + 1) TH2 = new_fabric_admin.NewController(nodeId=112233) ``` @@ -524,22 +488,22 @@ params = self.OpenCommissioningWindow(dev_ctrl=self.default_controller, node_id= ``` To create a new controller on the SAME fabric, allocate a new controller from -the fabric admin +the fabric admin. Fabric admin for default controller: ``` -fa=self.certificate_authority_manager.activeCaList[0].adminList[0] -second_ctrl = fa.new_fabric_admin.NewController(nodeId=node_id) + fa = self.certificate_authority_manager.activeCaList[0].adminList[0] + second_ctrl = fa.new_fabric_admin.NewController(nodeId=node_id) ``` -## other support functions +## Other support utilities -- basic_composition_support +- `basic_composition_support` - wildcard read, whole device analysis -- CommissioningFlowBlocks +- `CommissioningFlowBlocks` - various commissioning support for core tests -- spec_parsing_support +- `spec_parsing_support` - parsing data model XML into python readable format # Running tests locally @@ -564,12 +528,12 @@ or bootstrap.sh should be used for for the first setup, activate.sh may be used for subsequent setups as it is faster. -Next build the python wheels and create / activate a venv (called `py` here, but -any name may be used) +Next build the python wheels and create / activate a venv (called `pyenv` here, +but any name may be used) ``` -./scripts/build_python.sh -i py -source py/bin/activate +./scripts/build_python.sh -i pyenv +source pyenv/bin/activate ``` ## Running tests @@ -589,11 +553,11 @@ python3 src/python_testing/TC_ACE_1_2.py --commissioning-method on-network --qr- ``` Some tests require additional arguments (ex. PIXITs or configuration variables -for the CI). These arguments can be passed as sets of key-value pairs using the -`---arg` command line arguments. For example +for the CI). These arguments can be passed as sets of key/value pairs using the +`---arg:` command line arguments. For example: ``` ---int-arg PIXIT.ACE.APPENDPOINT:1 PIXIT.ACE.APPDEVTYPEID:0x0100 --string-arg PIXIT.ACE.APPCLUSTER:OnOff PIXIT.ACE.APPATTRIBUTE:OnOff +--int-arg PIXIT.ACE.APPENDPOINT:1 --int-arg PIXIT.ACE.APPDEVTYPEID:0x0100 --string-arg PIXIT.ACE.APPCLUSTER:OnOff --string-arg PIXIT.ACE.APPATTRIBUTE:OnOff ``` ## Local host app testing @@ -605,8 +569,75 @@ example DUT on the host and includes factory reset support # Running tests in CI -- add to .github/workflows/tests.yaml repl_tests_linux -- don’t forget to set the PICS file to the ci-pics-values -- if there are things in your test that will fail on CI (ex. test vendor +- Add test to the `repl_tests_linux` section of `.github/workflows/tests.yaml` +- Don’t forget to set the PICS file to the ci-pics-values +- If there are steps in your test that will fail on CI (e.g. test vendor checks), gate them on the PICS_SDK_CI_ONLY - - is_ci = self.check_pics('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 of the structured environment definition comments: + +``` +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# 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: +# === END CI TEST ARGUMENTS === +``` + +NOTE: The `=== BEGIN CI TEST ARGUMENTS ===` and `=== END CI TEST ARGUMENTS ===` +markers must be present. + +### 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..ac9c8f04e7f86f 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 | @@ -86,6 +87,7 @@ Generally regenerate using one of: | 155 | 0x9B | EnergyPreference | | 156 | 0x9C | PowerTopology | | 157 | 0x9D | EnergyEvseMode | +| 158 | 0x9E | WaterHeaterMode | | 159 | 0x9F | DeviceEnergyManagementMode | | 257 | 0x101 | DoorLock | | 258 | 0x102 | WindowCovering | @@ -130,6 +132,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..3ed93a0190c273 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; @@ -9262,6 +9265,48 @@ endpoint 2 { ram attribute clusterRevision default = 4; } } +endpoint 3 { + device type ma_genericswitch = 15, version 3; + + + server cluster Identify { + ram attribute identifyTime default = 0x0000; + ram attribute identifyType default = 0x00; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command Identify; + handle command TriggerEffect; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute tagList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster Switch { + emits event InitialPress; + emits event LongPress; + emits event LongRelease; + emits event MultiPressComplete; + ram attribute numberOfPositions default = 2; + ram attribute currentPosition default = 0; + ram attribute multiPressMax default = 3; + ram attribute featureMap default = 58; + ram attribute clusterRevision default = 2; + } +} endpoint 65534 { device type ma_secondary_network_interface = 25, version 1; diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index c547030731c6cf..4dd86543613c40 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -19,18 +19,18 @@ "package": [ { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/zcl/zcl-with-test-extensions.json", - "type": "zcl-properties", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", "category": "matter", - "version": 1, - "description": "Matter SDK ZCL data with some extensions" + "version": "chip-v1" }, { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", + "path": "../../../src/app/zap-templates/zcl/zcl-with-test-extensions.json", + "type": "zcl-properties", "category": "matter", - "version": "chip-v1" + "version": 1, + "description": "Matter SDK ZCL data with some extensions" } ], "endpointTypes": [ @@ -21900,6 +21900,14 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "StringEchoResponse", + "code": 13, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, { "name": "TestEnumsRequest", "code": 14, @@ -21973,32 +21981,24 @@ "isEnabled": 1 }, { - "name": "TestDifferentVendorMeiRequest", - "code": 4294049962, + "name": "StringEchoRequest", + "code": 24, "mfgCode": null, "source": "client", "isIncoming": 1, "isEnabled": 1 }, { - "name": "TestDifferentVendorMeiResponse", - "code": 4294049979, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "StringEchoRequest", - "code": 24, + "name": "TestDifferentVendorMeiRequest", + "code": 4294049962, "mfgCode": null, "source": "client", "isIncoming": 1, "isEnabled": 1 }, { - "name": "StringEchoResponse", - "code": 13, + "name": "TestDifferentVendorMeiResponse", + "code": 4294049979, "mfgCode": null, "source": "server", "isIncoming": 0, @@ -24783,6 +24783,465 @@ }, { "id": 4, + "name": "MA-genericswitch", + "deviceTypeRef": { + "code": 15, + "profileId": 259, + "label": "MA-genericswitch", + "name": "MA-genericswitch" + }, + "deviceTypes": [ + { + "code": 15, + "profileId": 259, + "label": "MA-genericswitch", + "name": "MA-genericswitch" + } + ], + "deviceVersions": [ + 3 + ], + "deviceIdentifiers": [ + 15 + ], + "deviceTypeName": "MA-genericswitch", + "deviceTypeCode": 15, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdentifyTime", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TagList", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Switch", + "code": 59, + "mfgCode": null, + "define": "SWITCH_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "NumberOfPositions", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentPosition", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "MultiPressMax", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "58", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "InitialPress", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "LongPress", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "LongRelease", + "code": 4, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "MultiPressComplete", + "code": 6, + "mfgCode": null, + "side": "server", + "included": 12 + } + ] + } + ] + }, + { + "id": 5, "name": "Anonymous Endpoint Type", "deviceTypeRef": { "code": 25, @@ -25315,9 +25774,17 @@ "parentEndpointIdentifier": null }, { - "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeName": "MA-genericswitch", "endpointTypeIndex": 3, "profileId": 259, + "endpointId": 3, + "networkId": 0, + "parentEndpointIdentifier": null + }, + { + "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeIndex": 4, + "profileId": 259, "endpointId": 65534, "networkId": 0, "parentEndpointIdentifier": null diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index dc41290765313a..7fd1d548609257 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -34,6 +34,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/ota" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/common" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/shell_extension" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/mode-support" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/icd/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" @@ -105,6 +106,8 @@ set(SRC_DIRS_LIST ) +set(EXCLUDE_SRCS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp") + if (CONFIG_ENABLE_PW_RPC) # Append additional directories for RPC build set(PRIV_INCLUDE_DIRS_LIST "${PRIV_INCLUDE_DIRS_LIST}" diff --git a/examples/all-clusters-app/esp32/main/main.cpp b/examples/all-clusters-app/esp32/main/main.cpp index b85f47d883c620..af94d2b2d36afe 100644 --- a/examples/all-clusters-app/esp32/main/main.cpp +++ b/examples/all-clusters-app/esp32/main/main.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -121,6 +122,13 @@ static void InitServer(intptr_t context) #if CONFIG_DEVICE_TYPE_M5STACK SetupPretendDevices(); #endif + CHIP_ERROR err = + app::Clusters::ModeSelect::StaticSupportedModesManager::getStaticSupportedModesManagerInstance().InitEndpointArray( + FIXED_ENDPOINT_COUNT); + if (err != CHIP_NO_ERROR) + { + ESP_LOGE(TAG, "Failed to initialize endpoint array for supported-modes, err:%" CHIP_ERROR_FORMAT, err.Format()); + } app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate); } 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/all-clusters-common/all-clusters-minimal-app.zap b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap index 090dda6a70e2e5..a5e9bdd3164ee2 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap @@ -17,13 +17,6 @@ } ], "package": [ - { - "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "category": "matter", - "version": "chip-v1" - }, { "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/zcl/zcl.json", @@ -31,6 +24,13 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "category": "matter", + "version": "chip-v1" } ], "endpointTypes": [ @@ -910,7 +910,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, 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/chef/devices/rootnode_airpurifier_73a6fe2651.zap b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.zap index d72b6d11800223..78aa987f1d8fa6 100644 --- a/examples/chef/devices/rootnode_airpurifier_73a6fe2651.zap +++ b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.zap @@ -17,13 +17,6 @@ } ], "package": [ - { - "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "category": "matter", - "version": "chip-v1" - }, { "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/zcl/zcl.json", @@ -31,6 +24,13 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "category": "matter", + "version": "chip-v1" } ], "endpointTypes": [ diff --git a/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.zap b/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.zap index 127d31dc60551f..535aa424e1d2a7 100644 --- a/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.zap +++ b/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.zap @@ -2997,7 +2997,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3013,7 +3013,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3029,7 +3029,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3045,7 +3045,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3061,7 +3061,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_pump_5f904818cc.zap b/examples/chef/devices/rootnode_pump_5f904818cc.zap index ca8e1ad91d30fc..f28d7cfbab317e 100644 --- a/examples/chef/devices/rootnode_pump_5f904818cc.zap +++ b/examples/chef/devices/rootnode_pump_5f904818cc.zap @@ -579,7 +579,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_pump_a811bb33a0.zap b/examples/chef/devices/rootnode_pump_a811bb33a0.zap index ad107294293b67..6314e3fb0c2e3a 100644 --- a/examples/chef/devices/rootnode_pump_a811bb33a0.zap +++ b/examples/chef/devices/rootnode_pump_a811bb33a0.zap @@ -579,7 +579,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.zap b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.zap index 6833a1a52bb222..a784ab5723b85f 100644 --- a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.zap +++ b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.zap @@ -17,13 +17,6 @@ } ], "package": [ - { - "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "category": "matter", - "version": "chip-v1" - }, { "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/zcl/zcl.json", 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/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap index 7cba96b7f511d6..64c948a5c8c233 100644 --- a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap +++ b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap @@ -563,7 +563,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap index 3caa58a4d7f042..0b05af158f1bde 100644 --- a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap +++ b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap @@ -563,7 +563,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, 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/energy-management-common/energy-management-app.zap b/examples/energy-management-app/energy-management-common/energy-management-app.zap index 597247dbc6998c..dc4b11c14c6742 100644 --- a/examples/energy-management-app/energy-management-common/energy-management-app.zap +++ b/examples/energy-management-app/energy-management-common/energy-management-app.zap @@ -627,7 +627,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, 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..00ca1204cc1f19 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,16 +38,45 @@ using namespace chip; namespace { // Constants +constexpr uint32_t kRpcTimeoutMs = 1000; constexpr uint32_t kDefaultChannelId = 1; // Fabric Bridge Client rpc::pw_rpc::nanopb::FabricBridge::Client fabricBridgeClient(rpc::client::GetDefaultRpcClient(), kDefaultChannelId); -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; + +// By passing the `call` parameter into WaitForResponse we are explicitly trying to insure the caller takes into consideration that +// the lifetime of the `call` object when calling WaitForResponse +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!"); @@ -81,52 +117,38 @@ CHIP_ERROR AddSynchronizedDevice(chip::NodeId nodeId) { ChipLogProgress(NotSpecified, "AddSynchronizedDevice"); - if (addSynchronizedDeviceCall.active()) - { - ChipLogError(NotSpecified, "Add Synchronized Device operation is in progress\n"); - return CHIP_ERROR_BUSY; - } - chip_rpc_SynchronizedDevice device; device.node_id = nodeId; - // By assigning the returned call to the global 'addSynchronizedDeviceCall', the RPC - // call is kept alive until it completes. When a response is received, it - // will be logged by the handler function and the call will complete. - addSynchronizedDeviceCall = fabricBridgeClient.AddSynchronizedDevice(device, OnAddDeviceResponseCompleted); + // The RPC call is kept alive until it completes. When a response is received, it will be logged by the handler + // function and the call will complete. + auto call = fabricBridgeClient.AddSynchronizedDevice(device, OnAddDeviceResponseCompleted); - if (!addSynchronizedDeviceCall.active()) + if (!call.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(call); } CHIP_ERROR RemoveSynchronizedDevice(chip::NodeId nodeId) { ChipLogProgress(NotSpecified, "RemoveSynchronizedDevice"); - if (removeSynchronizedDeviceCall.active()) - { - ChipLogError(NotSpecified, "Remove Synchronized Device operation is in progress\n"); - return CHIP_ERROR_BUSY; - } - chip_rpc_SynchronizedDevice device; device.node_id = nodeId; - // By assigning the returned call to the global 'removeSynchronizedDeviceCall', the RPC - // call is kept alive until it completes. When a response is received, it - // will be logged by the handler function and the call will complete. - removeSynchronizedDeviceCall = fabricBridgeClient.RemoveSynchronizedDevice(device, OnRemoveDeviceResponseCompleted); + // The RPC call is kept alive until it completes. When a response is received, it will be logged by the handler + // function and the call will complete. + auto call = fabricBridgeClient.RemoveSynchronizedDevice(device, OnRemoveDeviceResponseCompleted); - if (!removeSynchronizedDeviceCall.active()) + if (!call.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(call); } 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/fabric-bridge-common/BUILD.gn b/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn index 70d9586b699c0f..3bc4c23b9e0f92 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn +++ b/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn @@ -13,13 +13,32 @@ # limitations under the License. import("//build_overrides/chip.gni") - import("${chip_root}/src/app/chip_data_model.gni") +config("config") { + include_dirs = [ "include" ] +} + chip_data_model("fabric-bridge-common") { zap_file = "fabric-bridge-app.zap" - is_server = true - cflags = [ "-DDYNAMIC_ENDPOINT_COUNT=16" ] } + +source_set("fabric-bridge-lib") { + public_configs = [ ":config" ] + + sources = [ + "include/CHIPProjectAppConfig.h", + "include/Device.h", + "include/DeviceManager.h", + "src/Device.cpp", + "src/DeviceManager.cpp", + "src/ZCLCallbacks.cpp", + ] + + deps = [ + "${chip_root}/examples/fabric-bridge-app/fabric-bridge-common", + "${chip_root}/src/lib", + ] +} diff --git a/examples/fabric-bridge-app/linux/include/Device.h b/examples/fabric-bridge-app/fabric-bridge-common/include/Device.h similarity index 100% rename from examples/fabric-bridge-app/linux/include/Device.h rename to examples/fabric-bridge-app/fabric-bridge-common/include/Device.h diff --git a/examples/fabric-bridge-app/linux/include/DeviceManager.h b/examples/fabric-bridge-app/fabric-bridge-common/include/DeviceManager.h similarity index 100% rename from examples/fabric-bridge-app/linux/include/DeviceManager.h rename to examples/fabric-bridge-app/fabric-bridge-common/include/DeviceManager.h diff --git a/examples/fabric-bridge-app/linux/Device.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/Device.cpp similarity index 100% rename from examples/fabric-bridge-app/linux/Device.cpp rename to examples/fabric-bridge-app/fabric-bridge-common/src/Device.cpp diff --git a/examples/fabric-bridge-app/linux/DeviceManager.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/DeviceManager.cpp similarity index 100% rename from examples/fabric-bridge-app/linux/DeviceManager.cpp rename to examples/fabric-bridge-app/fabric-bridge-common/src/DeviceManager.cpp diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/ZCLCallbacks.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/ZCLCallbacks.cpp new file mode 100644 index 00000000000000..7a9521fa7820a7 --- /dev/null +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/ZCLCallbacks.cpp @@ -0,0 +1,92 @@ +/* + * + * 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. + */ + +#include "DeviceManager.h" + +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::app::Clusters; + +#define ZCL_DESCRIPTOR_CLUSTER_REVISION (1u) +#define ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_REVISION (2u) +#define ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_FEATURE_MAP (0u) + +// External attribute read callback function +Protocols::InteractionModel::Status emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, + uint8_t * buffer, uint16_t maxReadLength) +{ + uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); + AttributeId attributeId = attributeMetadata->attributeId; + + Device * dev = DeviceMgr().GetDevice(endpointIndex); + if (dev != nullptr && clusterId == app::Clusters::BridgedDeviceBasicInformation::Id) + { + using namespace app::Clusters::BridgedDeviceBasicInformation::Attributes; + ChipLogProgress(NotSpecified, "HandleReadBridgedDeviceBasicAttribute: attrId=%d, maxReadLength=%d", attributeId, + maxReadLength); + + if ((attributeId == Reachable::Id) && (maxReadLength == 1)) + { + *buffer = dev->IsReachable() ? 1 : 0; + } + else if ((attributeId == NodeLabel::Id) && (maxReadLength == 32)) + { + MutableByteSpan zclNameSpan(buffer, maxReadLength); + MakeZclCharString(zclNameSpan, dev->GetName()); + } + else if ((attributeId == ClusterRevision::Id) && (maxReadLength == 2)) + { + uint16_t rev = ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_REVISION; + memcpy(buffer, &rev, sizeof(rev)); + } + else if ((attributeId == FeatureMap::Id) && (maxReadLength == 4)) + { + uint32_t featureMap = ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_FEATURE_MAP; + memcpy(buffer, &featureMap, sizeof(featureMap)); + } + else + { + return Protocols::InteractionModel::Status::Failure; + } + return Protocols::InteractionModel::Status::Success; + } + + return Protocols::InteractionModel::Status::Failure; +} + +// External attribute write callback function +Protocols::InteractionModel::Status emberAfExternalAttributeWriteCallback(EndpointId endpoint, ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, + uint8_t * buffer) +{ + uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); + Protocols::InteractionModel::Status ret = Protocols::InteractionModel::Status::Failure; + + Device * dev = DeviceMgr().GetDevice(endpointIndex); + if (dev != nullptr && dev->IsReachable()) + { + ChipLogProgress(NotSpecified, "emberAfExternalAttributeWriteCallback: ep=%d, clusterId=%d", endpoint, clusterId); + ret = Protocols::InteractionModel::Status::Success; + } + + return ret; +} diff --git a/examples/fabric-bridge-app/linux/BUILD.gn b/examples/fabric-bridge-app/linux/BUILD.gn index 2b408d52625fea..d0f60f30fbb2b9 100644 --- a/examples/fabric-bridge-app/linux/BUILD.gn +++ b/examples/fabric-bridge-app/linux/BUILD.gn @@ -33,15 +33,12 @@ if (bridge_enable_pw_rpc) { executable("fabric-bridge-app") { sources = [ "${chip_root}/examples/fabric-bridge-app/fabric-bridge-common/include/CHIPProjectAppConfig.h", - "Device.cpp", - "DeviceManager.cpp", - "include/Device.h", - "include/DeviceManager.h", "main.cpp", ] deps = [ "${chip_root}/examples/fabric-bridge-app/fabric-bridge-common", + "${chip_root}/examples/fabric-bridge-app/fabric-bridge-common:fabric-bridge-lib", "${chip_root}/examples/platform/linux:app-main", "${chip_root}/src/lib", ] 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..02916b87aaa06a 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,45 @@ 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; + +// By passing the `call` parameter into WaitForResponse we are explicitly trying to insure the caller takes into consideration that +// the lifetime of the `call` object when calling WaitForResponse +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); @@ -67,22 +99,18 @@ CHIP_ERROR OpenCommissioningWindow(NodeId nodeId) { ChipLogProgress(NotSpecified, "OpenCommissioningWindow with Node Id 0x:" ChipLogFormatX64, ChipLogValueX64(nodeId)); - if (openCommissioningWindowCall.active()) - { - ChipLogError(NotSpecified, "OpenCommissioningWindow is in progress\n"); - return CHIP_ERROR_BUSY; - } - chip_rpc_DeviceInfo device; device.node_id = nodeId; - // The RPC will remain active as long as `openCommissioningWindowCall` is alive. - openCommissioningWindowCall = fabricAdminClient.OpenCommissioningWindow(device, OnOpenCommissioningWindowCompleted); + // The RPC call is kept alive until it completes. When a response is received, it will be logged by the handler + // function and the call will complete. + auto call = fabricAdminClient.OpenCommissioningWindow(device, OnOpenCommissioningWindowCompleted); - if (!openCommissioningWindowCall.active()) + if (!call.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(call); } 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/fabric-bridge-app/linux/main.cpp b/examples/fabric-bridge-app/linux/main.cpp index 2047e15877ee4c..0aa22b8445ee56 100644 --- a/examples/fabric-bridge-app/linux/main.cpp +++ b/examples/fabric-bridge-app/linux/main.cpp @@ -23,7 +23,6 @@ #include "DeviceManager.h" #include -#include #if defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE #include "RpcClient.h" @@ -40,10 +39,6 @@ using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::Clusters::AdministratorCommissioning; -#define ZCL_DESCRIPTOR_CLUSTER_REVISION (1u) -#define ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_REVISION (2u) -#define ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_FEATURE_MAP (0u) - namespace { constexpr uint16_t kPollIntervalMs = 100; @@ -158,6 +153,8 @@ AdministratorCommissioningCommandHandler gAdministratorCommissioningCommandHandl void ApplicationInit() { + ChipLogDetail(NotSpecified, "Fabric-Bridge: ApplicationInit()"); + InteractionModelEngine::GetInstance()->RegisterCommandHandler(&gAdministratorCommissioningCommandHandler); #if defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE @@ -172,7 +169,10 @@ void ApplicationInit() DeviceMgr().Init(); } -void ApplicationShutdown() {} +void ApplicationShutdown() +{ + ChipLogDetail(NotSpecified, "Fabric-Bridge: ApplicationShutdown()"); +} int main(int argc, char * argv[]) { @@ -185,65 +185,3 @@ int main(int argc, char * argv[]) return 0; } - -// External attribute read callback function -Protocols::InteractionModel::Status emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, - const EmberAfAttributeMetadata * attributeMetadata, - uint8_t * buffer, uint16_t maxReadLength) -{ - uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); - AttributeId attributeId = attributeMetadata->attributeId; - - Device * dev = DeviceMgr().GetDevice(endpointIndex); - if (dev != nullptr && clusterId == app::Clusters::BridgedDeviceBasicInformation::Id) - { - using namespace app::Clusters::BridgedDeviceBasicInformation::Attributes; - ChipLogProgress(NotSpecified, "HandleReadBridgedDeviceBasicAttribute: attrId=%d, maxReadLength=%d", attributeId, - maxReadLength); - - if ((attributeId == Reachable::Id) && (maxReadLength == 1)) - { - *buffer = dev->IsReachable() ? 1 : 0; - } - else if ((attributeId == NodeLabel::Id) && (maxReadLength == 32)) - { - MutableByteSpan zclNameSpan(buffer, maxReadLength); - MakeZclCharString(zclNameSpan, dev->GetName()); - } - else if ((attributeId == ClusterRevision::Id) && (maxReadLength == 2)) - { - uint16_t rev = ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_REVISION; - memcpy(buffer, &rev, sizeof(rev)); - } - else if ((attributeId == FeatureMap::Id) && (maxReadLength == 4)) - { - uint32_t featureMap = ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_FEATURE_MAP; - memcpy(buffer, &featureMap, sizeof(featureMap)); - } - else - { - return Protocols::InteractionModel::Status::Failure; - } - return Protocols::InteractionModel::Status::Success; - } - - return Protocols::InteractionModel::Status::Failure; -} - -// External attribute write callback function -Protocols::InteractionModel::Status emberAfExternalAttributeWriteCallback(EndpointId endpoint, ClusterId clusterId, - const EmberAfAttributeMetadata * attributeMetadata, - uint8_t * buffer) -{ - uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); - Protocols::InteractionModel::Status ret = Protocols::InteractionModel::Status::Failure; - - Device * dev = DeviceMgr().GetDevice(endpointIndex); - if (dev != nullptr && dev->IsReachable()) - { - ChipLogProgress(NotSpecified, "emberAfExternalAttributeWriteCallback: ep=%d, clusterId=%d", endpoint, clusterId); - ret = Protocols::InteractionModel::Status::Success; - } - - return ret; -} 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/light-switch-app/infineon/cyw30739/README.md b/examples/light-switch-app/infineon/cyw30739/README.md index 70d650cfef97a3..0343563087a154 100644 --- a/examples/light-switch-app/infineon/cyw30739/README.md +++ b/examples/light-switch-app/infineon/cyw30739/README.md @@ -12,7 +12,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Installing ModusToolbox™ Software](#installing-modustoolbox-software) - [ModusToolbox™ tools package](#modustoolbox-tools-package) - [Note for WSL (Windows Subsystem for Linux)](#note-for-wsl-windows-subsystem-for-linux) - - [Checkout Submodules](#checkout-submodules) + - [Checkout Submodules and Bootstrap](#checkout-submodules-and-bootstrap) - [Building](#building) - [Factory Data](#factory-data) - [Commissionable Data](#commissionable-data) @@ -65,7 +65,7 @@ If you are using WSL, please ensure you have installed the ModusToolbox™ Software for Linux. Running Windows tools directly from the WSL command line would cause path resolution failure in the build process. -### Checkout Submodules +### Checkout Submodules and Bootstrap Before building the example, check out the Matter repository and sync submodules using the following command: @@ -73,6 +73,7 @@ using the following command: ```bash $ cd ~/connectedhomeip $ scripts/checkout_submodules.py --platform infineon +$ bash scripts/bootstrap.sh -p all,infineon ``` ## Building diff --git a/examples/light-switch-app/qpg/zap/switch.zap b/examples/light-switch-app/qpg/zap/switch.zap index 0f65ac5eb64615..362ef409bebaa6 100644 --- a/examples/light-switch-app/qpg/zap/switch.zap +++ b/examples/light-switch-app/qpg/zap/switch.zap @@ -17,13 +17,6 @@ } ], "package": [ - { - "pathRelativity": "relativeToZap", - "path": "../../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "category": "matter", - "version": "chip-v1" - }, { "pathRelativity": "relativeToZap", "path": "../../../../src/app/zap-templates/zcl/zcl.json", @@ -31,6 +24,13 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "category": "matter", + "version": "chip-v1" } ], "endpointTypes": [ 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/lighting-app/infineon/cyw30739/README.md b/examples/lighting-app/infineon/cyw30739/README.md index b1ff7aa5304902..a69ddb0957c8fa 100644 --- a/examples/lighting-app/infineon/cyw30739/README.md +++ b/examples/lighting-app/infineon/cyw30739/README.md @@ -12,7 +12,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Installing ModusToolbox™ Software](#installing-modustoolbox-software) - [ModusToolbox™ tools package](#modustoolbox-tools-package) - [Note for WSL (Windows Subsystem for Linux)](#note-for-wsl-windows-subsystem-for-linux) - - [Checkout Submodules](#checkout-submodules) + - [Checkout Submodules and Bootstrap](#checkout-submodules-and-bootstrap) - [Building](#building) - [Factory Data](#factory-data) - [Commissionable Data](#commissionable-data) @@ -65,7 +65,7 @@ If you are using WSL, please ensure you have installed the ModusToolbox™ Software for Linux. Running Windows tools directly from the WSL command line would cause path resolution failure in the build process. -### Checkout Submodules +### Checkout Submodules and Bootstrap Before building the example, check out the Matter repository and sync submodules using the following command: @@ -73,6 +73,7 @@ using the following command: ```bash $ cd ~/connectedhomeip $ scripts/checkout_submodules.py --platform infineon +$ bash scripts/bootstrap.sh -p all,infineon ``` ## Building diff --git a/examples/lighting-app/lighting-common/lighting-app.zap b/examples/lighting-app/lighting-common/lighting-app.zap index 69ee10fe7794f0..6489a395b38c7e 100644 --- a/examples/lighting-app/lighting-common/lighting-app.zap +++ b/examples/lighting-app/lighting-common/lighting-app.zap @@ -19,18 +19,18 @@ "package": [ { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/zcl/zcl.json", - "type": "zcl-properties", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", "category": "matter", - "version": 1, - "description": "Matter SDK ZCL data" + "version": "chip-v1" }, { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", "category": "matter", - "version": "chip-v1" + "version": 1, + "description": "Matter SDK ZCL data" } ], "endpointTypes": [ diff --git a/examples/lighting-app/nxp/zap/lighting-on-off.zap b/examples/lighting-app/nxp/zap/lighting-on-off.zap index beccb5480ca340..839971a84dec9e 100644 --- a/examples/lighting-app/nxp/zap/lighting-on-off.zap +++ b/examples/lighting-app/nxp/zap/lighting-on-off.zap @@ -499,7 +499,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.zap b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.zap index ba855b3908feae..65236d3c49498e 100644 --- a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.zap +++ b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.zap @@ -19,18 +19,18 @@ "package": [ { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/zcl/zcl.json", - "type": "zcl-properties", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", "category": "matter", - "version": 1, - "description": "Matter SDK ZCL data" + "version": "chip-v1" }, { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", "category": "matter", - "version": "chip-v1" + "version": 1, + "description": "Matter SDK ZCL data" } ], "endpointTypes": [ @@ -712,7 +712,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/lock-app/infineon/cyw30739/README.md b/examples/lock-app/infineon/cyw30739/README.md index 2b7bd2094154df..0c9b769b665c2a 100644 --- a/examples/lock-app/infineon/cyw30739/README.md +++ b/examples/lock-app/infineon/cyw30739/README.md @@ -12,7 +12,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Installing ModusToolbox™ Software](#installing-modustoolbox-software) - [ModusToolbox™ tools package](#modustoolbox-tools-package) - [Note for WSL (Windows Subsystem for Linux)](#note-for-wsl-windows-subsystem-for-linux) - - [Checkout Submodules](#checkout-submodules) + - [Checkout Submodules and Bootstrap](#checkout-submodules-and-bootstrap) - [Building](#building) - [Factory Data](#factory-data) - [Commissionable Data](#commissionable-data) @@ -65,7 +65,7 @@ If you are using WSL, please ensure you have installed the ModusToolbox™ Software for Linux. Running Windows tools directly from the WSL command line would cause path resolution failure in the build process. -### Checkout Submodules +### Checkout Submodules and Bootstrap Before building the example, check out the Matter repository and sync submodules using the following command: @@ -73,6 +73,7 @@ using the following command: ```bash $ cd ~/connectedhomeip $ scripts/checkout_submodules.py --platform infineon +$ bash scripts/bootstrap.sh -p all,infineon ``` ## Building 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/lock-app/nxp/zap/lock-app.zap b/examples/lock-app/nxp/zap/lock-app.zap index ff1ead7297c757..70442ac916c7fe 100644 --- a/examples/lock-app/nxp/zap/lock-app.zap +++ b/examples/lock-app/nxp/zap/lock-app.zap @@ -499,7 +499,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.zap b/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.zap index 03113285ad2567..1df2afdd38fc8a 100644 --- a/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.zap +++ b/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.zap @@ -19,18 +19,18 @@ "package": [ { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/zcl/zcl.json", - "type": "zcl-properties", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", "category": "matter", - "version": 1, - "description": "Matter SDK ZCL data" + "version": "chip-v1" }, { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", "category": "matter", - "version": "chip-v1" + "version": 1, + "description": "Matter SDK ZCL data" } ], "endpointTypes": [ diff --git a/examples/ota-provider-app/ota-provider-common/ota-provider-app.zap b/examples/ota-provider-app/ota-provider-common/ota-provider-app.zap index c98b9e661328e5..b019c91de5ef04 100644 --- a/examples/ota-provider-app/ota-provider-common/ota-provider-app.zap +++ b/examples/ota-provider-app/ota-provider-common/ota-provider-app.zap @@ -19,18 +19,18 @@ "package": [ { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/zcl/zcl.json", - "type": "zcl-properties", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", "category": "matter", - "version": 1, - "description": "Matter SDK ZCL data" + "version": "chip-v1" }, { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", "category": "matter", - "version": "chip-v1" + "version": 1, + "description": "Matter SDK ZCL data" } ], "endpointTypes": [ diff --git a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter index f3eadf7c9db5d2..a0ae180bbc1307 100644 --- a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter +++ b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter @@ -1293,6 +1293,7 @@ cluster UserLabel = 65 { endpoint 0 { device type ma_rootdevice = 22, version 1; + device type ma_otarequestor = 18, version 1; binding cluster OtaSoftwareUpdateProvider; @@ -1301,6 +1302,10 @@ endpoint 0 { callback attribute serverList; callback attribute clientList; callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; } @@ -1313,6 +1318,9 @@ endpoint 0 { callback attribute subjectsPerAccessControlEntry; callback attribute targetsPerAccessControlEntry; callback attribute accessControlEntriesPerFabric; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; callback attribute clusterRevision; @@ -1343,6 +1351,10 @@ endpoint 0 { callback attribute capabilityMinima; callback attribute specificationVersion; callback attribute maxPathsPerInvoke; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; } @@ -1355,6 +1367,10 @@ endpoint 0 { ram attribute updatePossible default = 1; ram attribute updateState default = 0; ram attribute updateStateProgress default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1364,6 +1380,10 @@ endpoint 0 { server cluster LocalizationConfiguration { persist attribute activeLocale default = "en-US"; callback attribute supportedLocales; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; } @@ -1382,6 +1402,10 @@ endpoint 0 { callback attribute regulatoryConfig; callback attribute locationCapability; callback attribute supportsConcurrentConnection; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1402,6 +1426,10 @@ endpoint 0 { ram attribute lastNetworkingStatus; ram attribute lastNetworkID; ram attribute lastConnectErrorValue; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -1427,6 +1455,10 @@ endpoint 0 { callback attribute activeRadioFaults; callback attribute activeNetworkFaults; callback attribute testEventTriggersEnabled default = false; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1439,6 +1471,10 @@ endpoint 0 { callback attribute windowStatus; callback attribute adminFabricIndex; callback attribute adminVendorId; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1454,6 +1490,10 @@ endpoint 0 { callback attribute commissionedFabrics; callback attribute trustedRootCertificates; callback attribute currentFabricIndex; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1476,6 +1516,10 @@ endpoint 0 { callback attribute groupTable; callback attribute maxGroupsPerFabric; callback attribute maxGroupKeysPerFabric; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; diff --git a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap index 5291880efb89f0..ce4e60fe260d25 100644 --- a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap +++ b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap @@ -19,18 +19,18 @@ "package": [ { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/zcl/zcl.json", - "type": "zcl-properties", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", "category": "matter", - "version": 1, - "description": "Matter SDK ZCL data" + "version": "chip-v1" }, { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", "category": "matter", - "version": "chip-v1" + "version": 1, + "description": "Matter SDK ZCL data" } ], "endpointTypes": [ @@ -38,12 +38,18 @@ "id": 1, "name": "MA-rootdevice", "deviceTypeRef": { - "code": 22, + "code": 18, "profileId": 259, - "label": "MA-rootdevice", - "name": "MA-rootdevice" + "label": "MA-otarequestor", + "name": "MA-otarequestor" }, "deviceTypes": [ + { + "code": 18, + "profileId": 259, + "label": "MA-otarequestor", + "name": "MA-otarequestor" + }, { "code": 22, "profileId": 259, @@ -52,13 +58,15 @@ } ], "deviceVersions": [ + 1, 1 ], "deviceIdentifiers": [ + 18, 22 ], - "deviceTypeName": "MA-rootdevice", - "deviceTypeCode": 22, + "deviceTypeName": "MA-otarequestor", + "deviceTypeCode": 18, "deviceTypeProfileId": 259, "clusters": [ { @@ -96,7 +104,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65534, "reportableChange": 0 @@ -112,7 +120,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65534, "reportableChange": 0 @@ -128,11 +136,75 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -186,7 +258,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -202,7 +274,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -255,6 +327,54 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "AttributeList", "code": 65531, @@ -340,7 +460,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -356,7 +476,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -372,7 +492,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -388,7 +508,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -404,7 +524,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -420,7 +540,7 @@ "singleton": 1, "bounded": 0, "defaultValue": "", - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -436,7 +556,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -452,7 +572,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -468,7 +588,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -484,7 +604,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -500,7 +620,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -665,6 +785,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -772,6 +956,22 @@ } ], "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "ClusterRevision", "code": 65533, @@ -873,47 +1073,111 @@ "reportableChange": 0 }, { - "name": "FeatureMap", - "code": 65532, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", - "type": "bitmap32", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ClusterRevision", - "code": 65533, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 - } - ], - "events": [ + }, { - "name": "StateTransition", - "code": 0, + "name": "EventList", + "code": 65530, "mfgCode": null, "side": "server", - "included": 1 - }, - { + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StateTransition", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { "name": "VersionApplied", "code": 1, "mfgCode": null, @@ -948,7 +1212,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "en-US", - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -964,6 +1228,70 @@ "singleton": 0, "bounded": 0, "defaultValue": null, + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -1022,7 +1350,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0", - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -1231,6 +1559,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -1475,6 +1867,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -1548,39 +2004,103 @@ "code": 0, "mfgCode": null, "side": "server", - "type": "array", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RebootCount", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpTime", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TotalOperationalHours", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BootReason", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "BootReasonEnum", "included": 1, "storageOption": "External", "singleton": 0, "bounded": 0, "defaultValue": null, "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "RebootCount", - "code": 1, + "name": "ActiveHardwareFaults", + "code": 5, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, "bounded": 0, "defaultValue": null, "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "UpTime", - "code": 2, + "name": "ActiveRadioFaults", + "code": 6, "mfgCode": null, "side": "server", - "type": "int64u", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, @@ -1592,11 +2112,11 @@ "reportableChange": 0 }, { - "name": "TotalOperationalHours", - "code": 3, + "name": "ActiveNetworkFaults", + "code": 7, "mfgCode": null, "side": "server", - "type": "int32u", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, @@ -1608,24 +2128,24 @@ "reportableChange": 0 }, { - "name": "BootReason", - "code": 4, + "name": "TestEventTriggersEnabled", + "code": 8, "mfgCode": null, "side": "server", - "type": "BootReasonEnum", + "type": "boolean", "included": 1, "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "false", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ActiveHardwareFaults", - "code": 5, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", "type": "array", @@ -1633,15 +2153,15 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ActiveRadioFaults", - "code": 6, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, "side": "server", "type": "array", @@ -1649,15 +2169,15 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ActiveNetworkFaults", - "code": 7, + "name": "EventList", + "code": 65530, "mfgCode": null, "side": "server", "type": "array", @@ -1665,23 +2185,23 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "TestEventTriggersEnabled", - "code": 8, + "name": "AttributeList", + "code": 65531, "mfgCode": null, "side": "server", - "type": "boolean", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "false", + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -1812,6 +2332,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -2048,6 +2632,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -2204,6 +2852,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, diff --git a/examples/platform/esp32/mode-support/static-supported-modes-manager.cpp b/examples/platform/esp32/mode-support/static-supported-modes-manager.cpp new file mode 100644 index 00000000000000..d06a8b8b7dc809 --- /dev/null +++ b/examples/platform/esp32/mode-support/static-supported-modes-manager.cpp @@ -0,0 +1,223 @@ +/* + * + * Copyright (c) 2023 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 "static-supported-modes-manager.h" +#include + +using namespace chip; +using namespace chip::app::Clusters; +using namespace chip::DeviceLayer::Internal; +using namespace chip::app::Clusters::ModeSelect; +using chip::Protocols::InteractionModel::Status; + +using ModeOptionStructType = Structs::ModeOptionStruct::Type; +using SemanticTag = Structs::SemanticTagStruct::Type; + +template +using List = app::DataModel::List; + +SupportedModesManager::ModeOptionsProvider * StaticSupportedModesManager::epModeOptionsProviderList = nullptr; + +const StaticSupportedModesManager StaticSupportedModesManager::instance = StaticSupportedModesManager(); + +int StaticSupportedModesManager::mSize = 0; + +CHIP_ERROR StaticSupportedModesManager::InitEndpointArray(int size) +{ + if (epModeOptionsProviderList != nullptr) + { + ChipLogError(Zcl, "Cannot allocate epModeOptionsProviderList"); + return CHIP_ERROR_INCORRECT_STATE; + } + mSize = size; + epModeOptionsProviderList = new SupportedModesManager::ModeOptionsProvider[mSize]; + if (epModeOptionsProviderList == nullptr) + { + ChipLogError(Zcl, "Failed to allocate memory to epModeOptionsProviderList"); + return CHIP_ERROR_NO_MEMORY; + } + for (int i = 0; i < mSize; i++) + { + epModeOptionsProviderList[i] = ModeOptionsProvider(); + } + return CHIP_NO_ERROR; +} + +SupportedModesManager::ModeOptionsProvider StaticSupportedModesManager::getModeOptionsProvider(EndpointId endpointId) const +{ + if (epModeOptionsProviderList[endpointId].begin() != nullptr && epModeOptionsProviderList[endpointId].end() != nullptr) + { + return ModeOptionsProvider(epModeOptionsProviderList[endpointId].begin(), epModeOptionsProviderList[endpointId].end()); + } + + ModeOptionStructType * modeOptionStructList = nullptr; + SemanticTag * semanticTags = nullptr; + + char keyBuf[ESP32Config::kMaxConfigKeyNameLength]; + uint32_t supportedModeCount = 0; + + VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesCount(keyBuf, sizeof(keyBuf), endpointId) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr)); + ESP32Config::Key countKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(countKey, supportedModeCount) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr)); + + modeOptionStructList = new ModeOptionStructType[supportedModeCount]; + if (modeOptionStructList == nullptr) + { + return ModeOptionsProvider(nullptr, nullptr); + } + + epModeOptionsProviderList[endpointId] = ModeOptionsProvider(modeOptionStructList, modeOptionStructList + supportedModeCount); + + for (int index = 0; index < supportedModeCount; index++) + { + Structs::ModeOptionStruct::Type option; + uint32_t supportedModeMode = 0; + uint32_t semanticTagCount = 0; + size_t outLen = 0; + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesLabel(keyBuf, sizeof(keyBuf), endpointId, index) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key labelKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(labelKey, nullptr, 0, outLen) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + char * modeLabel = new char[outLen + 1]; + if (modeLabel == nullptr) + { + CleanUp(endpointId); + return ModeOptionsProvider(nullptr, nullptr); + } + + VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(labelKey, modeLabel, outLen + 1, outLen) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesValue(keyBuf, sizeof(keyBuf), endpointId, index) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key modeKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(labelKey, supportedModeMode) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagsCount(keyBuf, sizeof(keyBuf), endpointId, index) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key stCountKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(stCountKey, semanticTagCount) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + semanticTags = new SemanticTag[semanticTagCount]; + if (semanticTags == nullptr) + { + CleanUp(endpointId); + return ModeOptionsProvider(nullptr, nullptr); + } + for (auto stIndex = 0; stIndex < semanticTagCount; stIndex++) + { + + uint32_t semanticTagValue = 0; + uint32_t semanticTagMfgCode = 0; + SemanticTag tag; + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagValue(keyBuf, sizeof(keyBuf), endpointId, index, stIndex) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key stValueKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(stValueKey, semanticTagValue) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagMfgCode(keyBuf, sizeof(keyBuf), endpointId, index, stIndex) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key stMfgCodeKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(stMfgCodeKey, semanticTagMfgCode) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + tag.value = static_cast(semanticTagValue); + tag.mfgCode = static_cast(semanticTagMfgCode); + semanticTags[stIndex] = tag; + } + + option.label = chip::CharSpan::fromCharString(modeLabel); + option.mode = static_cast(supportedModeMode); + option.semanticTags = DataModel::List(semanticTags, semanticTagCount); + + modeOptionStructList[index] = option; + } + + return ModeOptionsProvider(modeOptionStructList, modeOptionStructList + supportedModeCount); +} + +Status StaticSupportedModesManager::getModeOptionByMode(unsigned short endpointId, unsigned char mode, + const ModeOptionStructType ** dataPtr) const +{ + auto modeOptionsProvider = this->getModeOptionsProvider(endpointId); + if (modeOptionsProvider.begin() == nullptr) + { + return Status::UnsupportedCluster; + } + auto * begin = modeOptionsProvider.begin(); + auto * end = modeOptionsProvider.end(); + + for (auto * it = begin; it != end; ++it) + { + auto & modeOption = *it; + if (modeOption.mode == mode) + { + *dataPtr = &modeOption; + return Status::Success; + } + } + ChipLogProgress(Zcl, "Cannot find the mode %u", mode); + return Status::InvalidCommand; +} + +const ModeSelect::SupportedModesManager * ModeSelect::getSupportedModesManager() +{ + return &StaticSupportedModesManager::getStaticSupportedModesManagerInstance(); +} + +void StaticSupportedModesManager::FreeSupportedModes(EndpointId endpointId) const +{ + if (epModeOptionsProviderList[endpointId].begin() != nullptr) + { + auto * begin = epModeOptionsProviderList[endpointId].begin(); + auto * end = epModeOptionsProviderList[endpointId].end(); + for (auto * it = begin; it != end; ++it) + { + auto & modeOption = *it; + delete[] modeOption.label.data(); + delete[] modeOption.semanticTags.data(); + } + delete[] begin; + } + epModeOptionsProviderList[endpointId] = ModeOptionsProvider(); +} + +void StaticSupportedModesManager::CleanUp(EndpointId endpointId) const +{ + ChipLogError(Zcl, "Supported mode data is in incorrect format"); + FreeSupportedModes(endpointId); +} diff --git a/examples/platform/esp32/mode-support/static-supported-modes-manager.h b/examples/platform/esp32/mode-support/static-supported-modes-manager.h new file mode 100644 index 00000000000000..8d6bb3c665ff0c --- /dev/null +++ b/examples/platform/esp32/mode-support/static-supported-modes-manager.h @@ -0,0 +1,80 @@ +/* + * + * Copyright (c) 2023 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 app { +namespace Clusters { +namespace ModeSelect { + +class StaticSupportedModesManager : public chip::app::Clusters::ModeSelect::SupportedModesManager +{ +private: + using ModeOptionStructType = Structs::ModeOptionStruct::Type; + using SemanticTag = Structs::SemanticTagStruct::Type; + static int mSize; + + static ModeOptionsProvider * epModeOptionsProviderList; + + void FreeSupportedModes(EndpointId endpointId) const; + + static const StaticSupportedModesManager instance; + +public: + // InitEndpointArray should be called only once in the application. Memory allocated to the + // epModeOptionsProviderList will be needed for the lifetime of the program, so it's never deallocated. + static CHIP_ERROR InitEndpointArray(int size); + + // DeInitEndpointArray should be called only when application need to reallocate memory of + // epModeOptionsProviderList ( Eg. Bridges ). + static void DeInitEndpointArray() + { + delete[] epModeOptionsProviderList; + epModeOptionsProviderList = nullptr; + mSize = 0; + } + + SupportedModesManager::ModeOptionsProvider getModeOptionsProvider(EndpointId endpointId) const override; + + Protocols::InteractionModel::Status getModeOptionByMode(EndpointId endpointId, uint8_t mode, + const ModeOptionStructType ** dataPtr) const override; + + void CleanUp(EndpointId endpointId) const; + + StaticSupportedModesManager() {} + + ~StaticSupportedModesManager() + { + for (int i = 0; i < mSize; i++) + { + FreeSupportedModes(i); + } + } + + static inline const StaticSupportedModesManager & getStaticSupportedModesManagerInstance() { return instance; } +}; + +const SupportedModesManager * getSupportedModesManager(); + +} // namespace ModeSelect +} // namespace Clusters +} // namespace app +} // namespace chip 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/pump-app/pump-common/pump-app.zap b/examples/pump-app/pump-common/pump-app.zap index c456f068835755..cb87c13835d08c 100644 --- a/examples/pump-app/pump-common/pump-app.zap +++ b/examples/pump-app/pump-common/pump-app.zap @@ -675,7 +675,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/pump-app/silabs/data_model/pump-thread-app.zap b/examples/pump-app/silabs/data_model/pump-thread-app.zap index c338b8de8155af..358703c49600cf 100644 --- a/examples/pump-app/silabs/data_model/pump-thread-app.zap +++ b/examples/pump-app/silabs/data_model/pump-thread-app.zap @@ -675,7 +675,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/pump-app/silabs/data_model/pump-wifi-app.zap b/examples/pump-app/silabs/data_model/pump-wifi-app.zap index c338b8de8155af..358703c49600cf 100644 --- a/examples/pump-app/silabs/data_model/pump-wifi-app.zap +++ b/examples/pump-app/silabs/data_model/pump-wifi-app.zap @@ -675,7 +675,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap b/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap index 168ddcd01592a5..040218e9083e23 100644 --- a/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap +++ b/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap @@ -675,7 +675,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp b/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp index c9b4a3ab7281f1..dc99728ccf90d5 100644 --- a/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp +++ b/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp @@ -78,7 +78,10 @@ CHIP_ERROR AppTask::Init() } // Register Smoke & Co Test Event Trigger - Server::GetInstance().GetTestEventTriggerDelegate()->AddHandler(&AlarmMgr()); + if (Server::GetInstance().GetTestEventTriggerDelegate() != nullptr) + { + Server::GetInstance().GetTestEventTriggerDelegate()->AddHandler(&AlarmMgr()); + } sAlarmLED.Init(LIGHT_LED); sAlarmLED.Set(false); diff --git a/examples/thermostat/infineon/cyw30739/README.md b/examples/thermostat/infineon/cyw30739/README.md index 6d37d24eb920ef..0b94884fe134a4 100644 --- a/examples/thermostat/infineon/cyw30739/README.md +++ b/examples/thermostat/infineon/cyw30739/README.md @@ -12,7 +12,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Installing ModusToolbox™ Software](#installing-modustoolbox-software) - [ModusToolbox™ tools package](#modustoolbox-tools-package) - [Note for WSL (Windows Subsystem for Linux)](#note-for-wsl-windows-subsystem-for-linux) - - [Checkout Submodules](#checkout-submodules) + - [Checkout Submodules and Bootstrap](#checkout-submodules-and-bootstrap) - [Building](#building) - [Factory Data](#factory-data) - [Commissionable Data](#commissionable-data) @@ -65,7 +65,7 @@ If you are using WSL, please ensure you have installed the ModusToolbox™ Software for Linux. Running Windows tools directly from the WSL command line would cause path resolution failure in the build process. -### Checkout Submodules +### Checkout Submodules and Bootstrap Before building the example, check out the Matter repository and sync submodules using the following command: @@ -73,6 +73,7 @@ using the following command: ```bash $ cd ~/connectedhomeip $ scripts/checkout_submodules.py --platform infineon +$ bash scripts/bootstrap.sh -p all,infineon ``` ## Building diff --git a/examples/thermostat/nxp/zap/thermostat_matter_thread.zap b/examples/thermostat/nxp/zap/thermostat_matter_thread.zap index 489e9e00ab44bf..8824bce22564b9 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_thread.zap +++ b/examples/thermostat/nxp/zap/thermostat_matter_thread.zap @@ -17,13 +17,6 @@ } ], "package": [ - { - "pathRelativity": "relativeToZap", - "path": "../../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "category": "matter", - "version": "chip-v1" - }, { "pathRelativity": "relativeToZap", "path": "../../../../src/app/zap-templates/zcl/zcl.json", @@ -31,6 +24,13 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "category": "matter", + "version": "chip-v1" } ], "endpointTypes": [ 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/examples/window-app/common/window-app.zap b/examples/window-app/common/window-app.zap index 5f689678cb9415..87d2ce831e4647 100644 --- a/examples/window-app/common/window-app.zap +++ b/examples/window-app/common/window-app.zap @@ -19,18 +19,18 @@ "package": [ { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/zcl/zcl.json", - "type": "zcl-properties", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", "category": "matter", - "version": 1, - "description": "Matter SDK ZCL data" + "version": "chip-v1" }, { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", "category": "matter", - "version": "chip-v1" + "version": 1, + "description": "Matter SDK ZCL data" } ], "endpointTypes": [ diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index a38d0c0f53441f..8a1624d292e305 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -64 : [NXP] Add `--break-system-packages` to pip install +65 : [nrfconnect] Update nRF Connect SDK version. diff --git a/integrations/docker/images/chip-cert-bins/Dockerfile b/integrations/docker/images/chip-cert-bins/Dockerfile index 5fe42c49dba935..60b0e00863d403 100644 --- a/integrations/docker/images/chip-cert-bins/Dockerfile +++ b/integrations/docker/images/chip-cert-bins/Dockerfile @@ -1,6 +1,6 @@ # Stage 1: Setup dependencies (based on chip-build). -FROM ubuntu:24.04 as chip-build-cert -LABEL org.opencontainers.image.source https://github.com/project-chip/connectedhomeip +FROM ubuntu:24.04 AS chip-build-cert +LABEL org.opencontainers.image.source=https://github.com/project-chip/connectedhomeip ARG TARGETPLATFORM # COMMITHASH defines the target commit to build from. May be passed in using --build-arg. ARG COMMITHASH=c1ec2d777456924dcaa59b53351b00d73caf378f @@ -123,11 +123,11 @@ RUN set -x \ software-properties-common \ && add-apt-repository universe \ && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \ - && python3 get-pip.py \ + && python3 get-pip.py --break-system-packages \ && : # last line RUN set -x \ - && pip3 install attrs coloredlogs PyGithub pygit future portpicker mobly click cxxfilt ghapi pandas tabulate \ + && pip3 install attrs coloredlogs PyGithub pygit future portpicker mobly click cxxfilt ghapi pandas tabulate --break-system-packages \ && : # last line # build and install gn @@ -162,7 +162,7 @@ RUN ./scripts/checkout_submodules.py --allow-changing-global-git-config --shallo RUN bash scripts/bootstrap.sh # Stage 2: Build. -FROM chip-build-cert as chip-build-cert-bins +FROM chip-build-cert AS chip-build-cert-bins SHELL ["/bin/bash", "-c"] @@ -260,7 +260,7 @@ RUN case ${TARGETPLATFORM} in \ RUN source scripts/activate.sh && scripts/build_python.sh -m platform -d true -i out/python_env # Stage 3: Copy relevant cert bins to a minimal image to reduce size. -FROM ubuntu:22.04 +FROM ubuntu:24.04 ENV TZ=Etc/UTC RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN apt-get update -y diff --git a/integrations/docker/images/stage-2/chip-build-nrf-platform/Dockerfile b/integrations/docker/images/stage-2/chip-build-nrf-platform/Dockerfile index 0ec2b78bca1782..57635bdfee1822 100644 --- a/integrations/docker/images/stage-2/chip-build-nrf-platform/Dockerfile +++ b/integrations/docker/images/stage-2/chip-build-nrf-platform/Dockerfile @@ -7,7 +7,7 @@ ARG VERSION=1 FROM ghcr.io/project-chip/chip-build:${VERSION} as build LABEL org.opencontainers.image.source https://github.com/project-chip/connectedhomeip # Compatible Nordic Connect SDK revision. -ARG NCS_REVISION=v2.6.0 +ARG NCS_REVISION=v2.7.0 # Requirements to clone SDKs in temporary container RUN set -x \ 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..b4af613c584c29 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,8 @@ 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/water-heater-mode-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/requirements.build.txt b/scripts/setup/requirements.build.txt index 82fe4cc08cea50..c9e8bad323bd85 100644 --- a/scripts/setup/requirements.build.txt +++ b/scripts/setup/requirements.build.txt @@ -1,8 +1,9 @@ # Minimal requirements for building stand-alone CHIP applications. # # The list of Python packages required to perform a minimal CHIP -# application build should be kept as small as possible. Ideally, -# core build scripts should depend only on the standard library. +# application build should be kept as small as possible. + +# Ideally, core build scripts should depend only on the standard library. # scripts/build click diff --git a/scripts/setup/requirements.infineon.txt b/scripts/setup/requirements.infineon.txt index 0a79ce1f3bfa63..97b60983b72f32 100644 --- a/scripts/setup/requirements.infineon.txt +++ b/scripts/setup/requirements.infineon.txt @@ -1,2 +1,4 @@ +ecdsa +intelhex leb128 zcbor 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/tests/py/metadata.py b/scripts/tests/py/metadata.py index 46ac1fe9ec8ab8..050f20f9920d6b 100644 --- a/scripts/tests/py/metadata.py +++ b/scripts/tests/py/metadata.py @@ -14,12 +14,18 @@ # limitations under the License. import re +import sys from dataclasses import dataclass from typing import Any, Dict, List import yaml +def bool_from_str(value: str) -> bool: + """Convert True/true/False/false strings to bool.""" + return value.strip().lower() == "true" + + @dataclass class Metadata: py_script_path: str @@ -58,16 +64,59 @@ def copy_from_dict(self, attr_dict: Dict[str, Any]) -> None: self.py_script_path = attr_dict["py_script_path"] if "factoryreset" in attr_dict: - self.factoryreset = bool(attr_dict["factoryreset"]) + self.factoryreset = bool_from_str(attr_dict["factoryreset"]) if "factoryreset_app_only" in attr_dict: - self.factoryreset_app_only = bool(attr_dict["factoryreset_app_only"]) + self.factoryreset_app_only = bool_from_str(attr_dict["factoryreset_app_only"]) if "script_gdb" in attr_dict: - self.script_gdb = bool(attr_dict["script_gdb"]) + self.script_gdb = bool_from_str(attr_dict["script_gdb"]) if "quiet" in attr_dict: - self.quiet = bool(attr_dict["quiet"]) + self.quiet = bool_from_str(attr_dict["quiet"]) + + +def extract_runs_arg_lines(py_script_path: str) -> Dict[str, Dict[str, str]]: + """Extract the run arguments from the CI test arguments blocks.""" + + found_ci_args_section = False + done_ci_args_section = False + + runs_def_ptrn = re.compile(r'^\s*#\s*test-runner-runs:\s*(?P.*)$') + arg_def_ptrn = re.compile( + r'^\s*#\s*test-runner-run/(?P[a-zA-Z0-9_]+)/(?P[a-zA-Z0-9_\-]+):\s*(?P.*)$') + + runs_arg_lines: Dict[str, Dict[str, str]] = {} + + with open(py_script_path, 'r', encoding='utf8') as py_script: + for line_idx, line in enumerate(py_script.readlines()): + line = line.strip() + line_num = line_idx + 1 + + # Detect the single CI args section, to skip the lines otherwise. + if not done_ci_args_section and line.startswith("# === BEGIN CI TEST ARGUMENTS ==="): + found_ci_args_section = True + elif found_ci_args_section and line.startswith("# === END CI TEST ARGUMENTS ==="): + done_ci_args_section = True + found_ci_args_section = False + + runs_match = runs_def_ptrn.match(line) + args_match = arg_def_ptrn.match(line) + + if not found_ci_args_section and (runs_match or args_match): + print(f"WARNING: {py_script_path}:{line_num}: Found CI args outside of CI TEST ARGUMENTS block!", file=sys.stderr) + continue + + if runs_match: + for run in runs_match.group("run_id").strip().split(): + runs_arg_lines[run] = {} + runs_arg_lines[run]['run'] = run + runs_arg_lines[run]['py_script_path'] = py_script_path + + elif args_match: + runs_arg_lines[args_match.group("run_id")][args_match.group("arg_name")] = args_match.group("arg_val") + + return runs_arg_lines class MetadataReader: @@ -126,33 +175,15 @@ def parse_script(self, py_script_path: str) -> List[Metadata]: the run arguments associated with a particular run defined in the script file. """ - - runs_def_ptrn = re.compile(r'^\s*#\s*test-runner-runs:\s*(.*)$') - arg_def_ptrn = re.compile(r'^\s*#\s*test-runner-run/([a-zA-Z0-9_]+)/([a-zA-Z0-9_\-]+):\s*(.*)$') - - runs_arg_lines: Dict[str, Dict[str, str]] = {} runs_metadata: List[Metadata] = [] - - with open(py_script_path, 'r', encoding='utf8') as py_script: - for line in py_script.readlines(): - runs_match = runs_def_ptrn.match(line.strip()) - args_match = arg_def_ptrn.match(line.strip()) - - if runs_match: - for run in runs_match.group(1).strip().split(): - runs_arg_lines[run] = {} - runs_arg_lines[run]['run'] = run - runs_arg_lines[run]['py_script_path'] = py_script_path - - elif args_match: - runs_arg_lines[args_match.group(1)][args_match.group(2)] = args_match.group(3) + runs_arg_lines = extract_runs_arg_lines(py_script_path) for run, attr in runs_arg_lines.items(): self.__resolve_env_vals__(attr) metadata = Metadata( py_script_path=attr.get("py_script_path", ""), - run=attr.get("run", ""), + run=run, app=attr.get("app", ""), app_args=attr.get("app_args", ""), script_args=attr.get("script_args", ""), diff --git a/scripts/tests/py/test_metadata.py b/scripts/tests/py/test_metadata.py index a0c12a0ab0ed5a..863add965c315e 100644 --- a/scripts/tests/py/test_metadata.py +++ b/scripts/tests/py/test_metadata.py @@ -21,13 +21,17 @@ class TestMetadataReader(unittest.TestCase): - test_file_content = ''' - # test-runner-runs: run1 + test_file_content = ''' + # === BEGIN CI TEST ARGUMENTS === + # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/app-args: --discriminator 1234 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --commissioning-method on-network --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True + # === END CI TEST ARGUMENTS === + + # test-runner-run/run1/quiet: False ''' env_file_content = ''' diff --git a/scripts/tools/generate_esp32_chip_factory_bin.py b/scripts/tools/generate_esp32_chip_factory_bin.py index b641ef05b6cd88..eab2ec6b43c229 100755 --- a/scripts/tools/generate_esp32_chip_factory_bin.py +++ b/scripts/tools/generate_esp32_chip_factory_bin.py @@ -159,6 +159,39 @@ def ishex(s): except ValueError: return False +# get_supported_modes_dict() converts the list of strings to per endpoint dictionaries. +# example with semantic tags +# input : ['0/label1/1/"1\0x8000, 2\0x8000" 1/label2/1/"1\0x8000, 2\0x8000"'] +# output : {'1': [{'Label': 'label1', 'Mode': 0, 'Semantic_Tag': [{'value': 1, 'mfgCode': 32768}, {'value': 2, 'mfgCode': 32768}]}, {'Label': 'label2', 'Mode': 1, 'Semantic_Tag': [{'value': 1, 'mfgCode': 32768}, {'value': 2, 'mfgCode': 32768}]}]} + +# example without semantic tags +# input : ['0/label1/1 1/label2/1'] +# output : {'1': [{'Label': 'label1', 'Mode': 0, 'Semantic_Tag': []}, {'Label': 'label2', 'Mode': 1, 'Semantic_Tag': []}]} + + +def get_supported_modes_dict(supported_modes): + output_dict = {} + + for mode_str in supported_modes: + mode_label_strs = mode_str.split('/') + mode = mode_label_strs[0] + label = mode_label_strs[1] + ep = mode_label_strs[2] + + semantic_tags = '' + if (len(mode_label_strs) == 4): + semantic_tag_strs = mode_label_strs[3].split(', ') + semantic_tags = [{"value": int(v.split('\\')[0]), "mfgCode": int(v.split('\\')[1], 16)} for v in semantic_tag_strs] + + mode_dict = {"Label": label, "Mode": int(mode), "Semantic_Tag": semantic_tags} + + if ep in output_dict: + output_dict[ep].append(mode_dict) + else: + output_dict[ep] = [mode_dict] + + return output_dict + def check_str_range(s, min_len, max_len, name): if s and ((len(s) < min_len) or (len(s) > max_len)): @@ -269,6 +302,60 @@ def populate_factory_data(args, spake2p_params): if args.hw_ver_str: FACTORY_DATA['hw-ver-str']['value'] = args.hw_ver_str + # SupportedModes are stored as multiple entries + # - sm-sz/ : number of supported modes for the endpoint + # - sm-label// : supported modes label key for the endpoint and index + # - sm-mode// : supported modes mode key for the endpoint and index + # - sm-st-sz// : supported modes SemanticTag key for the endpoint and index + # - st-v/// : semantic tag value key for the endpoint and index and ind + # - st-mfg/// : semantic tag mfg code key for the endpoint and index and ind + if (args.supported_modes is not None): + dictionary = get_supported_modes_dict(args.supported_modes) + for ep in dictionary.keys(): + _sz = { + 'type': 'data', + 'encoding': 'u32', + 'value': len(dictionary[ep]) + } + FACTORY_DATA.update({'sm-sz/{:x}'.format(int(ep)): _sz}) + for i in range(len(dictionary[ep])): + item = dictionary[ep][i] + _label = { + 'type': 'data', + 'encoding': 'string', + 'value': item["Label"] + } + _mode = { + 'type': 'data', + 'encoding': 'u32', + 'value': item["Mode"] + } + _st_sz = { + 'type': 'data', + 'encoding': 'u32', + 'value': len(item["Semantic_Tag"]) + } + FACTORY_DATA.update({'sm-label/{:x}/{:x}'.format(int(ep), i): _label}) + FACTORY_DATA.update({'sm-mode/{:x}/{:x}'.format(int(ep), i): _mode}) + FACTORY_DATA.update({'sm-st-sz/{:x}/{:x}'.format(int(ep), i): _st_sz}) + + for j in range(len(item["Semantic_Tag"])): + entry = item["Semantic_Tag"][j] + + _value = { + 'type': 'data', + 'encoding': 'u32', + 'value': entry["value"] + } + _mfg_code = { + 'type': 'data', + 'encoding': 'u32', + 'value': entry["mfgCode"] + } + + FACTORY_DATA.update({'st-v/{:x}/{:x}/{:x}'.format(int(ep), i, j): _value}) + FACTORY_DATA.update({'st-mfg/{:x}/{:x}/{:x}'.format(int(ep), i, j): _mfg_code}) + def gen_raw_ec_keypair_from_der(key_file, pubkey_raw_file, privkey_raw_file): with open(key_file, 'rb') as f: @@ -381,6 +468,9 @@ def any_base_int(s): return int(s, 0) help=('128-bit unique identifier for generating rotating device identifier, ' 'provide 32-byte hex string, e.g. "1234567890abcdef1234567890abcdef"')) + parser.add_argument('--supported-modes', type=str, nargs='+', required=False, + help='List of supported modes, eg: mode1/label1/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode" mode2/label2/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode" mode3/label3/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode"') + parser.add_argument('-s', '--size', type=any_base_int, default=0x6000, help='The size of the partition.bin, default: 0x6000') parser.add_argument('--target', default='esp32', @@ -419,8 +509,7 @@ def set_up_factory_data(args): def generate_factory_partiton_binary(args): generate_nvs_csv(args.output_dir, FACTORY_PARTITION_CSV) if args.generate_bin: - csv_file = os.path.join(args.output_dir, FACTORY_PARTITION_CSV) - generate_nvs_bin(args.encrypt, args.size, csv_file, FACTORY_PARTITION_BIN, args.output_dir) + generate_nvs_bin(args.encrypt, args.size, FACTORY_PARTITION_CSV, FACTORY_PARTITION_BIN, args.output_dir) print_flashing_help(args.encrypt, args.output_dir, FACTORY_PARTITION_BIN) clean_up() 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/access/tests/BUILD.gn b/src/access/tests/BUILD.gn index 702aade7f8c5e2..d8b43e6a17a01d 100644 --- a/src/access/tests/BUILD.gn +++ b/src/access/tests/BUILD.gn @@ -25,6 +25,7 @@ chip_test_suite("tests") { cflags = [ "-Wconversion" ] public_deps = [ "${chip_root}/src/access", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support:test_utils", "${dir_pw_unit_test}", ] diff --git a/src/access/tests/TestAccessControl.cpp b/src/access/tests/TestAccessControl.cpp index 16f30284fbc4d1..400ea04b76e535 100644 --- a/src/access/tests/TestAccessControl.cpp +++ b/src/access/tests/TestAccessControl.cpp @@ -19,9 +19,10 @@ #include "access/AccessControl.h" #include "access/examples/ExampleAccessControlDelegate.h" -#include +#include -#include +#include +#include namespace chip { namespace Access { 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/DefaultAttributePersistenceProvider.cpp b/src/app/DefaultAttributePersistenceProvider.cpp index 5bef4c11fb8c1a..6e7120999fe519 100644 --- a/src/app/DefaultAttributePersistenceProvider.cpp +++ b/src/app/DefaultAttributePersistenceProvider.cpp @@ -37,34 +37,40 @@ CHIP_ERROR DefaultAttributePersistenceProvider::InternalWriteValue(const Storage return mStorage->SyncSetKeyValue(aKey.KeyName(), aValue.data(), static_cast(aValue.size())); } -CHIP_ERROR DefaultAttributePersistenceProvider::InternalReadValue(const StorageKeyName & aKey, EmberAfAttributeType aType, - size_t aSize, MutableByteSpan & aValue) +CHIP_ERROR DefaultAttributePersistenceProvider::InternalReadValue(const StorageKeyName & aKey, MutableByteSpan & aValue) { VerifyOrReturnError(mStorage != nullptr, CHIP_ERROR_INCORRECT_STATE); uint16_t size = static_cast(min(aValue.size(), static_cast(UINT16_MAX))); ReturnErrorOnFailure(mStorage->SyncGetKeyValue(aKey.KeyName(), aValue.data(), size)); - EmberAfAttributeType type = aType; - if (emberAfIsStringAttributeType(type)) + aValue.reduce_size(size); + return CHIP_NO_ERROR; +} + +CHIP_ERROR DefaultAttributePersistenceProvider::InternalReadValue(const StorageKeyName & aKey, EmberAfAttributeType aType, + size_t aExpectedSize, MutableByteSpan & aValue) +{ + ReturnErrorOnFailure(InternalReadValue(aKey, aValue)); + size_t size = aValue.size(); + if (emberAfIsStringAttributeType(aType)) { // Ensure that we've read enough bytes that we are not ending up with // un-initialized memory. Should have read length + 1 (for the length // byte). - VerifyOrReturnError(size >= emberAfStringLength(aValue.data()) + 1, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(size >= 1 && size - 1 >= emberAfStringLength(aValue.data()), CHIP_ERROR_INCORRECT_STATE); } - else if (emberAfIsLongStringAttributeType(type)) + else if (emberAfIsLongStringAttributeType(aType)) { // Ensure that we've read enough bytes that we are not ending up with // un-initialized memory. Should have read length + 2 (for the length // bytes). - VerifyOrReturnError(size >= emberAfLongStringLength(aValue.data()) + 2, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(size >= 2 && size - 2 >= emberAfLongStringLength(aValue.data()), CHIP_ERROR_INCORRECT_STATE); } else { // Ensure we got the expected number of bytes for all other types. - VerifyOrReturnError(size == aSize, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(size == aExpectedSize, CHIP_ERROR_INVALID_ARGUMENT); } - aValue.reduce_size(size); return CHIP_NO_ERROR; } @@ -90,8 +96,7 @@ CHIP_ERROR DefaultAttributePersistenceProvider::SafeWriteValue(const ConcreteAtt CHIP_ERROR DefaultAttributePersistenceProvider::SafeReadValue(const ConcreteAttributePath & aPath, MutableByteSpan & aValue) { return InternalReadValue( - DefaultStorageKeyAllocator::SafeAttributeValue(aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId), 0x20, - aValue.size(), aValue); + DefaultStorageKeyAllocator::SafeAttributeValue(aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId), aValue); } namespace { diff --git a/src/app/DefaultAttributePersistenceProvider.h b/src/app/DefaultAttributePersistenceProvider.h index 4db77e8919222c..3e18808f366d37 100644 --- a/src/app/DefaultAttributePersistenceProvider.h +++ b/src/app/DefaultAttributePersistenceProvider.h @@ -63,7 +63,9 @@ class DefaultAttributePersistenceProvider : public AttributePersistenceProvider, private: CHIP_ERROR InternalWriteValue(const StorageKeyName & aKey, const ByteSpan & aValue); - CHIP_ERROR InternalReadValue(const StorageKeyName & aKey, EmberAfAttributeType aType, size_t aSize, MutableByteSpan & aValue); + CHIP_ERROR InternalReadValue(const StorageKeyName & aKey, MutableByteSpan & aValue); + CHIP_ERROR InternalReadValue(const StorageKeyName & aKey, EmberAfAttributeType aType, size_t aExpectedSize, + MutableByteSpan & aValue); }; } // namespace app 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/SafeAttributePersistenceProvider.h b/src/app/SafeAttributePersistenceProvider.h index ed02d6039043ad..8d11d95d47b02d 100644 --- a/src/app/SafeAttributePersistenceProvider.h +++ b/src/app/SafeAttributePersistenceProvider.h @@ -40,8 +40,8 @@ class SafeAttributePersistenceProvider // The following API provides helper functions to simplify the access of commonly used types. // The API may not be complete. - // Currently implemented write and read types are: uint8_t, uint16_t, uint32_t, unit64_t and - // their nullable varieties, and bool. + // Currently implemented write and read types are: bool, uint8_t, uint16_t, uint32_t, unit64_t and + // their nullable varieties, as well as ByteSpans. /** * Write an attribute value of type intX, uintX or bool to non-volatile memory. @@ -50,7 +50,7 @@ class SafeAttributePersistenceProvider * @param [in] aValue the data to write. */ template ::value, bool> = true> - CHIP_ERROR WriteScalarValue(const ConcreteAttributePath & aPath, T & aValue) + CHIP_ERROR WriteScalarValue(const ConcreteAttributePath & aPath, T aValue) { uint8_t value[sizeof(T)]; auto w = Encoding::LittleEndian::BufferWriter(value, sizeof(T)); @@ -71,18 +71,16 @@ class SafeAttributePersistenceProvider * * @param [in] aPath the attribute path for the data being persisted. * @param [in,out] aValue where to place the data. + * + * @retval CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND if no stored value exists for the attribute */ template ::value, bool> = true> CHIP_ERROR ReadScalarValue(const ConcreteAttributePath & aPath, T & aValue) { uint8_t attrData[sizeof(T)]; MutableByteSpan tempVal(attrData); - auto err = SafeReadValue(aPath, tempVal); - if (err != CHIP_NO_ERROR) - { - return err; - } - + ReturnErrorOnFailure(SafeReadValue(aPath, tempVal)); + VerifyOrReturnError(tempVal.size() == sizeof(T), CHIP_ERROR_INCORRECT_STATE); Encoding::LittleEndian::Reader r(tempVal.data(), tempVal.size()); r.RawReadLowLevelBeCareful(&aValue); return r.StatusCode(); @@ -95,7 +93,7 @@ class SafeAttributePersistenceProvider * @param [in] aValue the data to write. */ template ::value, bool> = true> - CHIP_ERROR WriteScalarValue(const ConcreteAttributePath & aPath, DataModel::Nullable & aValue) + CHIP_ERROR WriteScalarValue(const ConcreteAttributePath & aPath, const DataModel::Nullable & aValue) { typename NumericAttributeTraits::StorageType storageValue; if (aValue.IsNull()) @@ -114,16 +112,14 @@ class SafeAttributePersistenceProvider * * @param [in] aPath the attribute path for the data being persisted. * @param [in,out] aValue where to place the data. + * + * @retval CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND if no stored value exists for the attribute */ template ::value, bool> = true> CHIP_ERROR ReadScalarValue(const ConcreteAttributePath & aPath, DataModel::Nullable & aValue) { typename NumericAttributeTraits::StorageType storageValue; - CHIP_ERROR err = ReadScalarValue(aPath, storageValue); - if (err != CHIP_NO_ERROR) - { - return err; - } + ReturnErrorOnFailure(ReadScalarValue(aPath, storageValue)); if (NumericAttributeTraits::IsNullValue(storageValue)) { @@ -137,25 +133,25 @@ class SafeAttributePersistenceProvider return CHIP_NO_ERROR; } -protected: /** * Write an attribute value from the attribute store (i.e. not a struct or * list) to non-volatile memory. * * @param [in] aPath the attribute path for the data being written. - * @param [in] aValue the data to write. The value should be stored as-is. + * @param [in] aValue the data to write. The value will be stored as-is. */ virtual CHIP_ERROR SafeWriteValue(const ConcreteAttributePath & aPath, const ByteSpan & aValue) = 0; /** - * Read an attribute value from non-volatile memory. - * It can be assumed that this method will never be called upon to read - * an attribute of type string or long-string. + * Read an attribute value as a raw sequence of bytes from non-volatile memory. * * @param [in] aPath the attribute path for the data being persisted. * @param [in,out] aValue where to place the data. The size of the buffer - * will be equal to `aValue.size()`. The callee is expected to adjust - * aValue's size to the actual number of bytes read. + * will be equal to `aValue.size()`. On success aValue.size() + * will be the actual number of bytes read. + * + * @retval CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND if no stored value exists for the attribute + * @retval CHIP_ERROR_BUFFER_TOO_SMALL aValue.size() is too small to hold the value. */ virtual CHIP_ERROR SafeReadValue(const ConcreteAttributePath & aPath, MutableByteSpan & aValue) = 0; }; 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..d44f12b0f2b0bf --- /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.Value() == 0 || mValue.Value() == 0); + bool isIncrement = areBothValuesNonNull && (newValue.Value() > mValue.Value()); + bool isDecrement = areBothValuesNonNull && (newValue.Value() < mValue.Value()); + + 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..3ac4e07f234ba3 --- /dev/null +++ b/src/app/cluster-building-blocks/tests/BUILD.gn @@ -0,0 +1,31 @@ +# 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/core:string-builder-adapters", + "${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..a7750380285438 --- /dev/null +++ b/src/app/cluster-building-blocks/tests/TestQuieterReporting.cpp @@ -0,0 +1,263 @@ +/* + * + * 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 + +#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().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().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().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/administrator-commissioning-server/administrator-commissioning-server.cpp b/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp index 83a0b04281b1ad..a7b3eaed75fd7d 100644 --- a/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp +++ b/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp @@ -91,8 +91,8 @@ bool emberAfAdministratorCommissioningClusterOpenCommissioningWindowCallback( auto & iterations = commandData.iterations; auto & salt = commandData.salt; - Optional status = Optional::Missing(); - InteractionModel::Status globalStatus = InteractionModel::Status::Success; + Optional status = Optional::Missing(); + Status globalStatus = Status::Success; Spake2pVerifier verifier; ChipLogProgress(Zcl, "Received command to open commissioning window"); @@ -110,11 +110,9 @@ bool emberAfAdministratorCommissioningClusterOpenCommissioningWindowCallback( VerifyOrExit(iterations <= kSpake2p_Max_PBKDF_Iterations, status.Emplace(StatusCode::kPAKEParameterError)); VerifyOrExit(salt.size() >= kSpake2p_Min_PBKDF_Salt_Length, status.Emplace(StatusCode::kPAKEParameterError)); VerifyOrExit(salt.size() <= kSpake2p_Max_PBKDF_Salt_Length, status.Emplace(StatusCode::kPAKEParameterError)); - VerifyOrExit(commissioningTimeout <= commissionMgr.MaxCommissioningTimeout(), - globalStatus = InteractionModel::Status::InvalidCommand); - VerifyOrExit(commissioningTimeout >= commissionMgr.MinCommissioningTimeout(), - globalStatus = InteractionModel::Status::InvalidCommand); - VerifyOrExit(discriminator <= kMaxDiscriminatorValue, globalStatus = InteractionModel::Status::InvalidCommand); + VerifyOrExit(commissioningTimeout <= commissionMgr.MaxCommissioningTimeout(), globalStatus = Status::InvalidCommand); + VerifyOrExit(commissioningTimeout >= commissionMgr.MinCommissioningTimeout(), globalStatus = Status::InvalidCommand); + VerifyOrExit(discriminator <= kMaxDiscriminatorValue, globalStatus = Status::InvalidCommand); VerifyOrExit(verifier.Deserialize(pakeVerifier) == CHIP_NO_ERROR, status.Emplace(StatusCode::kPAKEParameterError)); VerifyOrExit(commissionMgr.OpenEnhancedCommissioningWindow(commissioningTimeout, discriminator, verifier, iterations, salt, @@ -130,7 +128,7 @@ bool emberAfAdministratorCommissioningClusterOpenCommissioningWindowCallback( } else { - if (globalStatus != InteractionModel::Status::Success) + if (globalStatus != Status::Success) { ChipLogError(Zcl, "Failed to open commissioning window. Global status " ChipLogFormatIMStatus, ChipLogValueIMStatus(globalStatus)); @@ -147,8 +145,8 @@ bool emberAfAdministratorCommissioningClusterOpenBasicCommissioningWindowCallbac MATTER_TRACE_SCOPE("OpenBasicCommissioningWindow", "AdministratorCommissioning"); auto commissioningTimeout = System::Clock::Seconds16(commandData.commissioningTimeout); - Optional status = Optional::Missing(); - InteractionModel::Status globalStatus = InteractionModel::Status::Success; + Optional status = Optional::Missing(); + Status globalStatus = Status::Success; ChipLogProgress(Zcl, "Received command to open basic commissioning window"); FabricIndex fabricIndex = commandObj->GetAccessingFabricIndex(); @@ -160,10 +158,8 @@ bool emberAfAdministratorCommissioningClusterOpenBasicCommissioningWindowCallbac VerifyOrExit(!commissionMgr.IsCommissioningWindowOpen(), status.Emplace(StatusCode::kBusy)); VerifyOrExit(failSafeContext.IsFailSafeFullyDisarmed(), status.Emplace(StatusCode::kBusy)); - VerifyOrExit(commissioningTimeout <= commissionMgr.MaxCommissioningTimeout(), - globalStatus = InteractionModel::Status::InvalidCommand); - VerifyOrExit(commissioningTimeout >= commissionMgr.MinCommissioningTimeout(), - globalStatus = InteractionModel::Status::InvalidCommand); + VerifyOrExit(commissioningTimeout <= commissionMgr.MaxCommissioningTimeout(), globalStatus = Status::InvalidCommand); + VerifyOrExit(commissioningTimeout >= commissionMgr.MinCommissioningTimeout(), globalStatus = Status::InvalidCommand); VerifyOrExit(commissionMgr.OpenBasicCommissioningWindowForAdministratorCommissioningCluster( commissioningTimeout, fabricIndex, fabricInfo->GetVendorId()) == CHIP_NO_ERROR, status.Emplace(StatusCode::kPAKEParameterError)); @@ -177,7 +173,7 @@ bool emberAfAdministratorCommissioningClusterOpenBasicCommissioningWindowCallbac } else { - if (globalStatus != InteractionModel::Status::Success) + if (globalStatus != Status::Success) { ChipLogError(Zcl, "Failed to open commissioning window. Global status " ChipLogFormatIMStatus, ChipLogValueIMStatus(globalStatus)); 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/dishwasher-alarm-server/dishwasher-alarm-server.cpp b/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.cpp index ca0fc231d6cc94..b3c9b8edbccf34 100644 --- a/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.cpp +++ b/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.cpp @@ -129,12 +129,13 @@ Status DishwasherAlarmServer::GetSupportedValue(EndpointId endpoint, BitMask supported) { Status status = Status::Success; - ; + if ((status = Attributes::Supported::Set(endpoint, supported)) != Status::Success) { ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: writing supported, err:0x%x", to_underlying(status)); return status; } + // Whenever there is change in Supported attribute, Latch should change accordingly (if possible). BitMask latch; if (GetLatchValue(endpoint, &latch) == Status::Success && !supported.HasAll(latch)) 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/icd-management-server/icd-management-server.cpp b/src/app/clusters/icd-management-server/icd-management-server.cpp index e4ead150a1fd79..55f6b5129c0a41 100644 --- a/src/app/clusters/icd-management-server/icd-management-server.cpp +++ b/src/app/clusters/icd-management-server/icd-management-server.cpp @@ -259,10 +259,10 @@ Status ICDManagementServer::RegisterClient(CommandHandler * commandObj, const Co bool isClientAdmin = false; // Check if ClientType is valid - VerifyOrReturnError(clientType != ClientTypeEnum::kUnknownEnumValue, InteractionModel::Status::ConstraintError); + VerifyOrReturnError(clientType != ClientTypeEnum::kUnknownEnumValue, Status::ConstraintError); // Check if client is admin - VerifyOrReturnError(CHIP_NO_ERROR == CheckAdmin(commandObj, commandPath, isClientAdmin), InteractionModel::Status::Failure); + VerifyOrReturnError(CHIP_NO_ERROR == CheckAdmin(commandObj, commandPath, isClientAdmin), Status::Failure); bool isFirstEntryForFabric = false; ICDMonitoringTable table(*mStorage, fabricIndex, mICDConfigurationData->GetClientsSupportedPerFabric(), mSymmetricKeystore); @@ -275,14 +275,14 @@ Status ICDManagementServer::RegisterClient(CommandHandler * commandObj, const Co // Existing entry: Validate Key if, and only if, the ISD does NOT have administrator permissions if (!isClientAdmin) { - VerifyOrReturnError(verificationKey.HasValue(), InteractionModel::Status::Failure); - VerifyOrReturnError(entry.IsKeyEquivalent(verificationKey.Value()), InteractionModel::Status::Failure); + VerifyOrReturnError(verificationKey.HasValue(), Status::Failure); + VerifyOrReturnError(entry.IsKeyEquivalent(verificationKey.Value()), Status::Failure); } } else if (CHIP_ERROR_NOT_FOUND == err) { // New entry - VerifyOrReturnError(entry.index < table.Limit(), InteractionModel::Status::ResourceExhausted); + VerifyOrReturnError(entry.index < table.Limit(), Status::ResourceExhausted); // Check if it's going to be the first entry for fabric isFirstEntryForFabric = table.IsEmpty(); @@ -290,7 +290,7 @@ Status ICDManagementServer::RegisterClient(CommandHandler * commandObj, const Co else { // Error - return InteractionModel::Status::Failure; + return Status::Failure; } // Save @@ -304,8 +304,8 @@ Status ICDManagementServer::RegisterClient(CommandHandler * commandObj, const Co } err = entry.SetKey(key); - VerifyOrReturnError(CHIP_ERROR_INVALID_ARGUMENT != err, InteractionModel::Status::ConstraintError); - VerifyOrReturnError(CHIP_NO_ERROR == err, InteractionModel::Status::Failure); + VerifyOrReturnError(CHIP_ERROR_INVALID_ARGUMENT != err, Status::ConstraintError); + VerifyOrReturnError(CHIP_NO_ERROR == err, Status::Failure); err = table.Set(entry.index, entry); // Delete key upon failure to prevent key storage leakage. @@ -314,8 +314,8 @@ Status ICDManagementServer::RegisterClient(CommandHandler * commandObj, const Co entry.DeleteKey(); } - VerifyOrReturnError(CHIP_ERROR_INVALID_ARGUMENT != err, InteractionModel::Status::ConstraintError); - VerifyOrReturnError(CHIP_NO_ERROR == err, InteractionModel::Status::Failure); + VerifyOrReturnError(CHIP_ERROR_INVALID_ARGUMENT != err, Status::ConstraintError); + VerifyOrReturnError(CHIP_NO_ERROR == err, Status::Failure); if (isFirstEntryForFabric) { @@ -324,7 +324,7 @@ Status ICDManagementServer::RegisterClient(CommandHandler * commandObj, const Co } icdCounter = mICDConfigurationData->GetICDCounter().GetValue(); - return InteractionModel::Status::Success; + return Status::Success; } Status ICDManagementServer::UnregisterClient(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, @@ -336,32 +336,32 @@ Status ICDManagementServer::UnregisterClient(CommandHandler * commandObj, const bool isClientAdmin = false; // Check if client is admin - VerifyOrReturnError(CHIP_NO_ERROR == CheckAdmin(commandObj, commandPath, isClientAdmin), InteractionModel::Status::Failure); + VerifyOrReturnError(CHIP_NO_ERROR == CheckAdmin(commandObj, commandPath, isClientAdmin), Status::Failure); ICDMonitoringTable table(*mStorage, fabricIndex, mICDConfigurationData->GetClientsSupportedPerFabric(), mSymmetricKeystore); // Get current entry, if exists ICDMonitoringEntry entry(mSymmetricKeystore); CHIP_ERROR err = table.Find(nodeId, entry); - VerifyOrReturnError(CHIP_ERROR_NOT_FOUND != err, InteractionModel::Status::NotFound); - VerifyOrReturnError(CHIP_NO_ERROR == err, InteractionModel::Status::Failure); + VerifyOrReturnError(CHIP_ERROR_NOT_FOUND != err, Status::NotFound); + VerifyOrReturnError(CHIP_NO_ERROR == err, Status::Failure); // Existing entry: Validate Key if, and only if, the ISD has NOT administrator permissions if (!isClientAdmin) { - VerifyOrReturnError(verificationKey.HasValue(), InteractionModel::Status::Failure); - VerifyOrReturnError(entry.IsKeyEquivalent(verificationKey.Value()), InteractionModel::Status::Failure); + VerifyOrReturnError(verificationKey.HasValue(), Status::Failure); + VerifyOrReturnError(entry.IsKeyEquivalent(verificationKey.Value()), Status::Failure); } err = table.Remove(entry.index); - VerifyOrReturnError(CHIP_NO_ERROR == err, InteractionModel::Status::Failure); + VerifyOrReturnError(CHIP_NO_ERROR == err, Status::Failure); if (table.IsEmpty()) { TriggerICDMTableUpdatedEvent(); } - return InteractionModel::Status::Success; + return Status::Success; } void ICDManagementServer::TriggerICDMTableUpdatedEvent() @@ -396,9 +396,9 @@ bool emberAfIcdManagementClusterRegisterClientCallback(CommandHandler * commandO uint32_t icdCounter = 0; ICDManagementServer server; - InteractionModel::Status status = server.RegisterClient(commandObj, commandPath, commandData, icdCounter); + Status status = server.RegisterClient(commandObj, commandPath, commandData, icdCounter); - if (InteractionModel::Status::Success == status) + if (Status::Success == status) { // Response IcdManagement::Commands::RegisterClientResponse::Type response{ .ICDCounter = icdCounter }; @@ -419,7 +419,7 @@ bool emberAfIcdManagementClusterUnregisterClientCallback(CommandHandler * comman const Commands::UnregisterClient::DecodableType & commandData) { ICDManagementServer server; - InteractionModel::Status status = server.UnregisterClient(commandObj, commandPath, commandData); + Status status = server.UnregisterClient(commandObj, commandPath, commandData); commandObj->AddStatus(commandPath, status); return true; 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/CodegenDataModel_Write.cpp b/src/app/codegen-data-model/CodegenDataModel_Write.cpp index 0805bfec6cbd18..999f35ea7836cf 100644 --- a/src/app/codegen-data-model/CodegenDataModel_Write.cpp +++ b/src/app/codegen-data-model/CodegenDataModel_Write.cpp @@ -166,8 +166,8 @@ CHIP_ERROR DecodeIntoEmberBuffer(AttributeValueDecoder & decoder, bool isNullabl // Nullable(0xFF) is not representable because 0xFF is the encoding of NULL in ember // as well as odd-sized integers (e.g. full 32-bit value like 0x11223344 cannot be written // to a 3-byte odd-sized integger). - VerifyOrReturnError(Traits::CanRepresentValue(isNullable, *workingValue), CHIP_ERROR_INVALID_ARGUMENT); - Traits::WorkingToStorage(*workingValue, storageValue); + VerifyOrReturnError(Traits::CanRepresentValue(isNullable, workingValue.Value()), CHIP_ERROR_INVALID_ARGUMENT); + Traits::WorkingToStorage(workingValue.Value(), storageValue); } VerifyOrReturnError(out.size() >= sizeof(storageValue), CHIP_ERROR_INVALID_ARGUMENT); 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..796c845ebe7787 100644 --- a/src/app/codegen-data-model/tests/TestCodegenModelViaMocks.cpp +++ b/src/app/codegen-data-model/tests/TestCodegenModelViaMocks.cpp @@ -14,9 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include + +#include + +#include "app/ConcreteCommandPath.h" #include #include +#include #include #include @@ -52,9 +59,6 @@ #include #include -#include -#include - using namespace chip; using namespace chip::Test; using namespace chip::app; @@ -69,6 +73,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 +2437,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/data-model-interface/tests/BUILD.gn b/src/app/data-model-interface/tests/BUILD.gn index f366ee718fc3a3..94faf695f687af 100644 --- a/src/app/data-model-interface/tests/BUILD.gn +++ b/src/app/data-model-interface/tests/BUILD.gn @@ -21,5 +21,8 @@ chip_test_suite("tests") { cflags = [ "-Wconversion" ] - public_deps = [ "${chip_root}/src/app/data-model-interface" ] + public_deps = [ + "${chip_root}/src/app/data-model-interface", + "${chip_root}/src/lib/core:string-builder-adapters", + ] } diff --git a/src/app/data-model-interface/tests/TestEventEmitting.cpp b/src/app/data-model-interface/tests/TestEventEmitting.cpp index 81a89f1603a04b..fe4e37e57b7dd0 100644 --- a/src/app/data-model-interface/tests/TestEventEmitting.cpp +++ b/src/app/data-model-interface/tests/TestEventEmitting.cpp @@ -19,9 +19,10 @@ #include #include #include +#include #include -#include +#include namespace { diff --git a/src/app/data-model/Nullable.h b/src/app/data-model/Nullable.h index f56e67ced19113..660c889e789518 100644 --- a/src/app/data-model/Nullable.h +++ b/src/app/data-model/Nullable.h @@ -45,8 +45,11 @@ struct Nullable : protected std::optional // all constructors of the base class within this derived class. // using std::optional::optional; - using std::optional::operator*; - using std::optional::operator->; + + // Do NOT pull in optional::operator* or optional::operator->, because that + // leads people to write code that looks like it should work, and compiles, + // but does not do the right things with TLV encoding and decoding, when + // nullable data model objects are involved. Nullable(NullOptionalType) : std::optional(std::nullopt) {} diff --git a/src/app/icd/server/tests/BUILD.gn b/src/app/icd/server/tests/BUILD.gn index e96954a97dde58..95ece1d28ae4df 100644 --- a/src/app/icd/server/tests/BUILD.gn +++ b/src/app/icd/server/tests/BUILD.gn @@ -31,6 +31,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/app/icd/server:manager", "${chip_root}/src/app/icd/server:monitoring-table", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/lib/support:testing", "${chip_root}/src/messaging/tests:helpers", diff --git a/src/app/icd/server/tests/TestICDManager.cpp b/src/app/icd/server/tests/TestICDManager.cpp index 0b3c1a459441dd..3672955bdf4b26 100644 --- a/src/app/icd/server/tests/TestICDManager.cpp +++ b/src/app/icd/server/tests/TestICDManager.cpp @@ -15,6 +15,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include + #include #include #include @@ -24,10 +27,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -124,18 +127,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 +148,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 +160,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 +177,8 @@ class TestICDManager : public ::testing::Test DeviceLayer::SetSystemLayerForTesting(nullptr); DeviceLayer::PlatformMgr().Shutdown(); - pMessagingContext->TearDownTestSuite(); + + LoopbackMessagingContext::TearDownTestSuite(); if (pMockClock != nullptr) { @@ -188,31 +186,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 +568,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 +973,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/icd/server/tests/TestICDMonitoringTable.cpp b/src/app/icd/server/tests/TestICDMonitoringTable.cpp index 423bc1506b36fb..177f8caba507e1 100644 --- a/src/app/icd/server/tests/TestICDMonitoringTable.cpp +++ b/src/app/icd/server/tests/TestICDMonitoringTable.cpp @@ -15,12 +15,14 @@ * limitations under the License. */ +#include + #include #include #include -#include #include #include +#include #include #include diff --git a/src/app/server/Server.cpp b/src/app/server/Server.cpp index a71d797651b418..5be815f0864c95 100644 --- a/src/app/server/Server.cpp +++ b/src/app/server/Server.cpp @@ -182,6 +182,10 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams) mReportScheduler = initParams.reportScheduler; mTestEventTriggerDelegate = initParams.testEventTriggerDelegate; + if (mTestEventTriggerDelegate == nullptr) + { + ChipLogProgress(AppServer, "WARNING: mTestEventTriggerDelegate is null"); + } deviceInfoprovider = DeviceLayer::GetDeviceInfoProvider(); if (deviceInfoprovider) @@ -359,7 +363,10 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams) chip::app::InteractionModelEngine::GetInstance()); // Register Test Event Trigger Handler - mTestEventTriggerDelegate->AddHandler(&mICDManager); + if (mTestEventTriggerDelegate != nullptr) + { + mTestEventTriggerDelegate->AddHandler(&mICDManager); + } #endif // CHIP_CONFIG_ENABLE_ICD_SERVER @@ -612,7 +619,10 @@ void Server::Shutdown() Credentials::SetGroupDataProvider(nullptr); #if CHIP_CONFIG_ENABLE_ICD_SERVER // Remove Test Event Trigger Handler - mTestEventTriggerDelegate->RemoveHandler(&mICDManager); + if (mTestEventTriggerDelegate != nullptr) + { + mTestEventTriggerDelegate->RemoveHandler(&mICDManager); + } mICDManager.Shutdown(); #endif // CHIP_CONFIG_ENABLE_ICD_SERVER mAttributePersister.Shutdown(); 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..bbded462985012 100644 --- a/src/app/tests/TestAclEvent.cpp +++ b/src/app/tests/TestAclEvent.cpp @@ -18,7 +18,6 @@ #include -#include #include #include @@ -27,11 +26,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -172,21 +173,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 +185,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 +199,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 +217,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 +227,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 +235,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 +257,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 +265,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 +284,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 +292,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 +316,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 +324,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/TestAttributePersistenceProvider.cpp b/src/app/tests/TestAttributePersistenceProvider.cpp index 7ae40b52402fe0..1b8c7ee3d3872c 100644 --- a/src/app/tests/TestAttributePersistenceProvider.cpp +++ b/src/app/tests/TestAttributePersistenceProvider.cpp @@ -59,7 +59,13 @@ TEST_F(TestAttributePersistenceProvider, TestStorageAndRetrivalByteSpans) MutableByteSpan valueReadBack(getArray); err = persistenceProvider.SafeReadValue(TestConcretePath, valueReadBack); EXPECT_EQ(err, CHIP_NO_ERROR); - EXPECT_TRUE(std::equal(valueReadBack.begin(), valueReadBack.end(), value.begin(), value.end())); + EXPECT_TRUE(valueReadBack.data_equal(value)); + + uint8_t getArrayThatIsLongerThanNeeded[10]; + MutableByteSpan valueReadBack2(getArrayThatIsLongerThanNeeded); + err = persistenceProvider.SafeReadValue(TestConcretePath, valueReadBack2); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(valueReadBack2.data_equal(value)); // Finishing persistenceProvider.Shutdown(); @@ -320,6 +326,7 @@ TEST_F(TestAttributePersistenceProvider, TestBufferTooSmallErrors) err = persistenceProvider.SafeReadValue(TestConcretePath, valueReadBackByteSpan8); EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL); + // TODO: ReadScalarValue() does not take a buffer, so expecting CHIP_ERROR_BUFFER_TOO_SMALL is bad API // Fail to get value as uint8_t uint8_t valueReadBack8; err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack8); 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..34f59edd245ff6 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 { @@ -166,27 +165,25 @@ struct BadFields } }; -InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aRequestCommandPath) +Protocols::InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aRequestCommandPath) { // Mock cluster catalog, only support commands on one cluster on one endpoint. - using InteractionModel::Status; - if (aRequestCommandPath.mEndpointId != kTestEndpointId) { - return Status::UnsupportedEndpoint; + return Protocols::InteractionModel::Status::UnsupportedEndpoint; } if (aRequestCommandPath.mClusterId != kTestClusterId) { - return Status::UnsupportedCluster; + return Protocols::InteractionModel::Status::UnsupportedCluster; } if (aRequestCommandPath.mCommandId == kTestNonExistCommandId) { - return Status::UnsupportedCommand; + return Protocols::InteractionModel::Status::UnsupportedCommand; } - return Status::Success; + return Protocols::InteractionModel::Status::Success; } void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPath, chip::TLV::TLVReader & aReader, @@ -347,7 +344,7 @@ class MockCommandHandlerCallback : public CommandHandlerImpl::Callback { DispatchSingleClusterCommand(aCommandPath, apPayload, &apCommandObj); } - InteractionModel::Status CommandExists(const ConcreteCommandPath & aCommandPath) + Protocols::InteractionModel::Status CommandExists(const ConcreteCommandPath & aCommandPath) { return ServerClusterCommandExists(aCommandPath); } @@ -357,25 +354,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 +424,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 +666,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 +698,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 +720,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 +737,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 +768,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 +789,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 +806,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 +837,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 +857,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 +874,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 +904,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 +924,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 +966,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 +1004,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 +1020,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 +1047,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 +1076,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 +1103,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 +1156,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 +1170,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) @@ -1273,7 +1253,8 @@ TEST_F(TestCommandInteraction, TestCommandHandler_WithOnInvokeReceivedNotExistCo mockCommandHandlerDelegate.ResetCounter(); MockCommandResponder mockCommandResponder; - InteractionModel::Status status = commandHandler.OnInvokeCommandRequest(mockCommandResponder, std::move(commandDatabuf), false); + Protocols::InteractionModel::Status status = + commandHandler.OnInvokeCommandRequest(mockCommandResponder, std::move(commandDatabuf), false); EXPECT_EQ(status, Protocols::InteractionModel::Status::InvalidAction); EXPECT_TRUE(mockCommandResponder.mChunks.IsNull()); @@ -1317,18 +1298,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 +1317,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 +1357,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 +1385,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 +1421,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 +1443,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 +1527,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 +1542,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 +1559,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 +1583,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 +1593,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 +1604,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); @@ -1668,8 +1649,8 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_RejectsMultipleCo mockCommandHandlerDelegate.ResetCounter(); commandDispatchedCount = 0; - InteractionModel::Status status = commandHandler.ProcessInvokeRequest(std::move(commandDatabuf), false); - EXPECT_EQ(status, InteractionModel::Status::InvalidAction); + Protocols::InteractionModel::Status status = commandHandler.ProcessInvokeRequest(std::move(commandDatabuf), false); + EXPECT_EQ(status, Protocols::InteractionModel::Status::InvalidAction); EXPECT_EQ(commandDispatchedCount, 0u); } @@ -1683,8 +1664,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); @@ -1721,8 +1702,9 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_RejectMultipleCom CommandHandlerImpl commandHandler(&mockCommandHandlerDelegate); MockCommandResponder mockCommandResponder; - InteractionModel::Status status = commandHandler.OnInvokeCommandRequest(mockCommandResponder, std::move(commandDatabuf), false); - EXPECT_EQ(status, InteractionModel::Status::InvalidAction); + Protocols::InteractionModel::Status status = + commandHandler.OnInvokeCommandRequest(mockCommandResponder, std::move(commandDatabuf), false); + EXPECT_EQ(status, Protocols::InteractionModel::Status::InvalidAction); EXPECT_TRUE(mockCommandResponder.mChunks.IsNull()); EXPECT_EQ(commandDispatchedCount, 0u); @@ -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); @@ -1777,8 +1759,8 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_AcceptMultipleCom mockCommandHandlerDelegate.ResetCounter(); commandDispatchedCount = 0; - InteractionModel::Status status = commandHandler.ProcessInvokeRequest(std::move(commandDatabuf), false); - EXPECT_EQ(status, InteractionModel::Status::Success); + Protocols::InteractionModel::Status status = commandHandler.ProcessInvokeRequest(std::move(commandDatabuf), false); + EXPECT_EQ(status, Protocols::InteractionModel::Status::Success); EXPECT_EQ(commandDispatchedCount, 2u); } @@ -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/TestFailSafeContext.cpp b/src/app/tests/TestFailSafeContext.cpp index fa13990d4f7947..8d164fad2d42db 100644 --- a/src/app/tests/TestFailSafeContext.cpp +++ b/src/app/tests/TestFailSafeContext.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #include #include 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..f0d3b0cc60d935 100644 --- a/src/app/tests/TestReportingEngine.cpp +++ b/src/app/tests/TestReportingEngine.cpp @@ -24,6 +24,8 @@ #include +#include + #include #include #include @@ -31,15 +33,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include - -using TestContext = chip::Test::AppContext; namespace chip { @@ -51,26 +51,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 +144,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 +176,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 +236,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/TestDescriptorCluster.yaml b/src/app/tests/suites/TestDescriptorCluster.yaml index b6b2cbc73e9f42..21a43fbe3c1cd0 100644 --- a/src/app/tests/suites/TestDescriptorCluster.yaml +++ b/src/app/tests/suites/TestDescriptorCluster.yaml @@ -82,7 +82,7 @@ tests: command: "readAttribute" attribute: "PartsList" response: - value: [1, 2] + value: [1, 2, 3] - label: "Read attribute ClusterRevision" command: "readAttribute" 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/tests/suites/commands/interaction_model/InteractionModel.cpp b/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp index 04e658f18cc188..a3f9f3ff6de892 100644 --- a/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp +++ b/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp @@ -19,7 +19,20 @@ #include "InteractionModel.h" using namespace chip; -using namespace chip::app; + +using chip::app::AttributePathParams; +using chip::app::CommandSender; +using chip::app::ConcreteAttributePath; +using chip::app::ConcreteCommandPath; +using chip::app::ConcreteDataAttributePath; +using chip::app::DataVersionFilter; +using chip::app::EventHeader; +using chip::app::EventPathParams; +using chip::app::InteractionModelEngine; +using chip::app::ReadClient; +using chip::app::ReadPrepareParams; +using chip::app::StatusIB; +using chip::app::WriteClient; namespace chip { namespace test_utils { diff --git a/src/app/zap-templates/zcl/data-model/all.xml b/src/app/zap-templates/zcl/data-model/all.xml index 23709faca1ace5..6003a7cf4a3f1a 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,8 @@ + + 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/mode-base-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml index 111df8eca07eff..b8e81233473932 100644 --- a/src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml @@ -32,6 +32,7 @@ This is because zap does not currently support generating code for clusters that + @@ -47,6 +48,7 @@ This is because zap does not currently support generating code for clusters that + 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/data-model/chip/water-heater-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml new file mode 100644 index 00000000000000..23a1b2eec5d4c0 --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + General + Water Heater Mode + 0x009E + WATER_HEATER_MODE_CLUSTER + true + true + Attributes and commands for selecting a mode from a list of supported options. + + + + + + + + + + SupportedModes + CurrentMode + StartUpMode + OnMode + + + + + This command is used to change device modes. + On receipt of this command the device SHALL respond with a ChangeToModeResponse command. + + + + + + + This command is sent by the device on receipt of the ChangeToModeWithStatus command. + + + + + + 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..3b11954f1582b0 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,8 @@ "valve-configuration-and-control-cluster.xml", "wake-on-lan-cluster.xml", "washer-controls-cluster.xml", + "water-heater-management-cluster.xml", + "water-heater-mode-cluster.xml", "wifi-network-diagnostics-cluster.xml", "wifi-network-management-cluster.xml", "window-covering.xml", @@ -641,6 +644,7 @@ "Power Topology": ["FeatureMap"], "Valve Configuration and Control": ["RemainingDuration"], "Boolean State Configuration": ["CurrentSensitivityLevel"], + "Water Heater Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], "Wi-Fi Network Management": ["SSID"] }, "defaultReportingPolicy": "mandatory", diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index e3ec959ff64e83..b03da7bc7b1e67 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,8 @@ "valve-configuration-and-control-cluster.xml", "wake-on-lan-cluster.xml", "washer-controls-cluster.xml", + "water-heater-management-cluster.xml", + "water-heater-mode-cluster.xml", "wifi-network-diagnostics-cluster.xml", "wifi-network-management-cluster.xml", "window-covering.xml", @@ -639,6 +642,7 @@ "Power Topology": ["FeatureMap"], "Valve Configuration and Control": ["RemainingDuration"], "Boolean State Configuration": ["CurrentSensitivityLevel"], + "Water Heater Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], "Wi-Fi Network Management": ["SSID"] }, "defaultReportingPolicy": "mandatory", 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/ble/tests/BUILD.gn b/src/ble/tests/BUILD.gn index ac897ab40a9c27..cfc5b5cb67be25 100644 --- a/src/ble/tests/BUILD.gn +++ b/src/ble/tests/BUILD.gn @@ -31,6 +31,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/ble", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/platform", ] } diff --git a/src/ble/tests/TestBleErrorStr.cpp b/src/ble/tests/TestBleErrorStr.cpp index 6868532823d950..7e3f0f51d5bfc4 100644 --- a/src/ble/tests/TestBleErrorStr.cpp +++ b/src/ble/tests/TestBleErrorStr.cpp @@ -28,13 +28,13 @@ #include #include +#include + #include #define _CHIP_BLE_BLE_H #include -#include - using namespace chip; // Test input data. diff --git a/src/ble/tests/TestBleLayer.cpp b/src/ble/tests/TestBleLayer.cpp index 5377e4465f66c5..29c8c472198221 100644 --- a/src/ble/tests/TestBleLayer.cpp +++ b/src/ble/tests/TestBleLayer.cpp @@ -21,9 +21,10 @@ #include #include -#include +#include #include +#include #include #include #include diff --git a/src/ble/tests/TestBleUUID.cpp b/src/ble/tests/TestBleUUID.cpp index 445535594fae4b..e4284001f138dd 100644 --- a/src/ble/tests/TestBleUUID.cpp +++ b/src/ble/tests/TestBleUUID.cpp @@ -27,7 +27,7 @@ #define _CHIP_BLE_BLE_H #include -#include +#include using namespace chip; using namespace chip::Ble; diff --git a/src/ble/tests/TestBtpEngine.cpp b/src/ble/tests/TestBtpEngine.cpp index 2b8fb1ff84b562..e565ac2a30de91 100644 --- a/src/ble/tests/TestBtpEngine.cpp +++ b/src/ble/tests/TestBtpEngine.cpp @@ -20,6 +20,9 @@ #include #include +#include + +#include #include #include @@ -27,8 +30,6 @@ #include #include -#include - using namespace chip; using namespace chip::Ble; 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..066f34e20d2731 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; @@ -5111,6 +5172,56 @@ cluster EnergyEvseMode = 157 { command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } +/** Attributes and commands for selecting a mode from a list of supported options. */ +cluster WaterHeaterMode = 158 { + revision 1; + + enum ModeTag : enum16 { + kOff = 16384; + kManual = 16385; + kTimed = 16386; + } + + bitmap Feature : bitmap32 { + kOnOff = 0x1; + } + + struct ModeTagStruct { + optional vendor_id mfgCode = 0; + enum16 value = 1; + } + + struct ModeOptionStruct { + char_string<64> label = 0; + int8u mode = 1; + ModeTagStruct modeTags[] = 2; + } + + readonly attribute ModeOptionStruct supportedModes[] = 0; + readonly attribute int8u currentMode = 1; + attribute optional nullable int8u startUpMode = 2; + attribute optional nullable int8u onMode = 3; + 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 ChangeToModeRequest { + int8u newMode = 0; + } + + response struct ChangeToModeResponse = 1 { + enum8 status = 0; + optional char_string statusText = 1; + } + + /** This command is used to change device modes. + On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ + command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; +} + /** Attributes and commands for selecting a mode from a list of supported options. */ provisional cluster DeviceEnergyManagementMode = 159 { revision 1; @@ -8010,18 +8121,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 +8140,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 +8158,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 +9245,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/data_model/controller-clusters.zap b/src/controller/data_model/controller-clusters.zap index abba3d15cd18ca..3c95a3320ba91b 100644 --- a/src/controller/data_model/controller-clusters.zap +++ b/src/controller/data_model/controller-clusters.zap @@ -4754,6 +4754,7 @@ "define": "THREAD_BORDER_ROUTER_MANAGEMENT_CLUSTER", "side": "client", "enabled": 1, + "apiMaturity": "provisional", "commands": [ { "name": "GetActiveDatasetRequest", @@ -4771,17 +4772,9 @@ "isIncoming": 0, "isEnabled": 1 }, - { - "name": "SetActiveDatasetRequest", - "code": 4, - "mfgCode": null, - "source": "client", - "isIncoming": 0, - "isEnabled": 1 - }, { "name": "SetPendingDatasetRequest", - "code": 5, + "code": 4, "mfgCode": null, "source": "client", "isIncoming": 0, diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index e96b2925e77a65..98e208fd3815ee 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)); @@ -32742,35 +33153,287 @@ public interface AttributeListAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } - public void readEnergyBalancesAttribute( - EnergyBalancesAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ENERGY_BALANCES_ATTRIBUTE_ID); + public void readEnergyBalancesAttribute( + EnergyBalancesAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ENERGY_BALANCES_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ENERGY_BALANCES_ATTRIBUTE_ID, true); + } + + public void subscribeEnergyBalancesAttribute( + EnergyBalancesAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ENERGY_BALANCES_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ENERGY_BALANCES_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readCurrentEnergyBalanceAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID, true); + } + + public void writeCurrentEnergyBalanceAttribute(DefaultClusterCallback callback, Integer value) { + writeCurrentEnergyBalanceAttribute(callback, value, 0); + } + + public void writeCurrentEnergyBalanceAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = new UIntType(value); + writeAttribute(new WriteAttributesCallbackImpl(callback), CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeCurrentEnergyBalanceAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readEnergyPrioritiesAttribute( + EnergyPrioritiesAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ENERGY_PRIORITIES_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ENERGY_PRIORITIES_ATTRIBUTE_ID, true); + } + + public void subscribeEnergyPrioritiesAttribute( + EnergyPrioritiesAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ENERGY_PRIORITIES_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ENERGY_PRIORITIES_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readLowPowerModeSensitivitiesAttribute( + LowPowerModeSensitivitiesAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, LOW_POWER_MODE_SENSITIVITIES_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, LOW_POWER_MODE_SENSITIVITIES_ATTRIBUTE_ID, true); + } + + public void subscribeLowPowerModeSensitivitiesAttribute( + LowPowerModeSensitivitiesAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, LOW_POWER_MODE_SENSITIVITIES_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, LOW_POWER_MODE_SENSITIVITIES_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readCurrentLowPowerModeSensitivityAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_LOW_POWER_MODE_SENSITIVITY_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CURRENT_LOW_POWER_MODE_SENSITIVITY_ATTRIBUTE_ID, true); + } + + public void writeCurrentLowPowerModeSensitivityAttribute(DefaultClusterCallback callback, Integer value) { + writeCurrentLowPowerModeSensitivityAttribute(callback, value, 0); + } + + public void writeCurrentLowPowerModeSensitivityAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = new UIntType(value); + writeAttribute(new WriteAttributesCallbackImpl(callback), CURRENT_LOW_POWER_MODE_SENSITIVITY_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeCurrentLowPowerModeSensitivityAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_LOW_POWER_MODE_SENSITIVITY_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CURRENT_LOW_POWER_MODE_SENSITIVITY_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) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, ENERGY_BALANCES_ATTRIBUTE_ID, true); + }, FEATURE_MAP_ATTRIBUTE_ID, true); } - public void subscribeEnergyBalancesAttribute( - EnergyBalancesAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ENERGY_BALANCES_ATTRIBUTE_ID); + 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) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, ENERGY_BALANCES_ATTRIBUTE_ID, minInterval, maxInterval); + }, FEATURE_MAP_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readCurrentEnergyBalanceAttribute( + public void readClusterRevisionAttribute( IntegerAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID); + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -32778,21 +33441,12 @@ public void onSuccess(byte[] tlv) { Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID, true); - } - - public void writeCurrentEnergyBalanceAttribute(DefaultClusterCallback callback, Integer value) { - writeCurrentEnergyBalanceAttribute(callback, value, 0); - } - - public void writeCurrentEnergyBalanceAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { - BaseTLVType tlvValue = new UIntType(value); - writeAttribute(new WriteAttributesCallbackImpl(callback), CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + }, CLUSTER_REVISION_ATTRIBUTE_ID, true); } - public void subscribeCurrentEnergyBalanceAttribute( + public void subscribeClusterRevisionAttribute( IntegerAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID); + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -32800,94 +33454,106 @@ public void onSuccess(byte[] tlv) { Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID, minInterval, maxInterval); + }, CLUSTER_REVISION_ATTRIBUTE_ID, minInterval, maxInterval); } + } - public void readEnergyPrioritiesAttribute( - EnergyPrioritiesAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ENERGY_PRIORITIES_ATTRIBUTE_ID); + public static class PowerTopologyCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 156L; - readAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, ENERGY_PRIORITIES_ATTRIBUTE_ID, true); + private static final long AVAILABLE_ENDPOINTS_ATTRIBUTE_ID = 0L; + private static final long ACTIVE_ENDPOINTS_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 PowerTopologyCluster(long devicePtr, int endpointId) { + super(devicePtr, endpointId, CLUSTER_ID); } - public void subscribeEnergyPrioritiesAttribute( - EnergyPrioritiesAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ENERGY_PRIORITIES_ATTRIBUTE_ID); + @Override + @Deprecated + public long initWithDevice(long devicePtr, int endpointId) { + return 0L; + } - subscribeAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, ENERGY_PRIORITIES_ATTRIBUTE_ID, minInterval, maxInterval); + public interface AvailableEndpointsAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); } - public void readLowPowerModeSensitivitiesAttribute( - LowPowerModeSensitivitiesAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, LOW_POWER_MODE_SENSITIVITIES_ATTRIBUTE_ID); + public interface ActiveEndpointsAttributeCallback 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 readAvailableEndpointsAttribute( + AvailableEndpointsAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, AVAILABLE_ENDPOINTS_ATTRIBUTE_ID); 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); } - }, LOW_POWER_MODE_SENSITIVITIES_ATTRIBUTE_ID, true); + }, AVAILABLE_ENDPOINTS_ATTRIBUTE_ID, true); } - public void subscribeLowPowerModeSensitivitiesAttribute( - LowPowerModeSensitivitiesAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, LOW_POWER_MODE_SENSITIVITIES_ATTRIBUTE_ID); + public void subscribeAvailableEndpointsAttribute( + AvailableEndpointsAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, AVAILABLE_ENDPOINTS_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); } - }, LOW_POWER_MODE_SENSITIVITIES_ATTRIBUTE_ID, minInterval, maxInterval); + }, AVAILABLE_ENDPOINTS_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readCurrentLowPowerModeSensitivityAttribute( - IntegerAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_LOW_POWER_MODE_SENSITIVITY_ATTRIBUTE_ID); + public void readActiveEndpointsAttribute( + ActiveEndpointsAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACTIVE_ENDPOINTS_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, CURRENT_LOW_POWER_MODE_SENSITIVITY_ATTRIBUTE_ID, true); - } - - public void writeCurrentLowPowerModeSensitivityAttribute(DefaultClusterCallback callback, Integer value) { - writeCurrentLowPowerModeSensitivityAttribute(callback, value, 0); - } - - public void writeCurrentLowPowerModeSensitivityAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { - BaseTLVType tlvValue = new UIntType(value); - writeAttribute(new WriteAttributesCallbackImpl(callback), CURRENT_LOW_POWER_MODE_SENSITIVITY_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + }, ACTIVE_ENDPOINTS_ATTRIBUTE_ID, true); } - public void subscribeCurrentLowPowerModeSensitivityAttribute( - IntegerAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_LOW_POWER_MODE_SENSITIVITY_ATTRIBUTE_ID); + public void subscribeActiveEndpointsAttribute( + ActiveEndpointsAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACTIVE_ENDPOINTS_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, CURRENT_LOW_POWER_MODE_SENSITIVITY_ATTRIBUTE_ID, minInterval, maxInterval); + }, ACTIVE_ENDPOINTS_ATTRIBUTE_ID, minInterval, maxInterval); } public void readGeneratedCommandListAttribute( @@ -33047,11 +33713,13 @@ public void onSuccess(byte[] tlv) { } } - public static class PowerTopologyCluster extends BaseChipCluster { - public static final long CLUSTER_ID = 156L; + public static class EnergyEvseModeCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 157L; - private static final long AVAILABLE_ENDPOINTS_ATTRIBUTE_ID = 0L; - private static final long ACTIVE_ENDPOINTS_ATTRIBUTE_ID = 1L; + private static final long SUPPORTED_MODES_ATTRIBUTE_ID = 0L; + private static final long CURRENT_MODE_ATTRIBUTE_ID = 1L; + private static final long START_UP_MODE_ATTRIBUTE_ID = 2L; + private static final long ON_MODE_ATTRIBUTE_ID = 3L; 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; @@ -33059,7 +33727,7 @@ public static class PowerTopologyCluster extends BaseChipCluster { private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L; private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L; - public PowerTopologyCluster(long devicePtr, int endpointId) { + public EnergyEvseModeCluster(long devicePtr, int endpointId) { super(devicePtr, endpointId, CLUSTER_ID); } @@ -33069,80 +33737,195 @@ public long initWithDevice(long devicePtr, int endpointId) { return 0L; } - public interface AvailableEndpointsAttributeCallback extends BaseAttributeCallback { - void onSuccess(List value); + public void changeToMode(ChangeToModeResponseCallback callback, Integer newMode) { + changeToMode(callback, newMode, 0); } - public interface ActiveEndpointsAttributeCallback extends BaseAttributeCallback { - void onSuccess(List value); + public void changeToMode(ChangeToModeResponseCallback callback, Integer newMode, int timedInvokeTimeoutMs) { + final long commandId = 0L; + + ArrayList elements = new ArrayList<>(); + final long newModeFieldID = 0L; + BaseTLVType newModetlvValue = new UIntType(newMode); + elements.add(new StructElement(newModeFieldID, newModetlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long statusFieldID = 0L; + Integer status = null; + final long statusTextFieldID = 1L; + Optional statusText = 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() == statusTextFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + statusText = Optional.of(castingValue.value(String.class)); + } + } + } + callback.onSuccess(status, statusText); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public interface ChangeToModeResponseCallback extends BaseClusterCallback { + void onSuccess(Integer status, Optional statusText); + } + + public interface SupportedModesAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface StartUpModeAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable Integer value); + } + + public interface OnModeAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable Integer 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 readSupportedModesAttribute( + SupportedModesAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_MODES_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SUPPORTED_MODES_ATTRIBUTE_ID, true); + } + + public void subscribeSupportedModesAttribute( + SupportedModesAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_MODES_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SUPPORTED_MODES_ATTRIBUTE_ID, minInterval, maxInterval); } - public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { - void onSuccess(List value); - } + public void readCurrentModeAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_MODE_ATTRIBUTE_ID); - public interface AcceptedCommandListAttributeCallback extends BaseAttributeCallback { - void onSuccess(List value); + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CURRENT_MODE_ATTRIBUTE_ID, true); } - public interface EventListAttributeCallback extends BaseAttributeCallback { - void onSuccess(List value); - } + public void subscribeCurrentModeAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_MODE_ATTRIBUTE_ID); - public interface AttributeListAttributeCallback extends BaseAttributeCallback { - void onSuccess(List value); + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CURRENT_MODE_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readAvailableEndpointsAttribute( - AvailableEndpointsAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, AVAILABLE_ENDPOINTS_ATTRIBUTE_ID); + public void readStartUpModeAttribute( + StartUpModeAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, START_UP_MODE_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, AVAILABLE_ENDPOINTS_ATTRIBUTE_ID, true); + }, START_UP_MODE_ATTRIBUTE_ID, true); } - public void subscribeAvailableEndpointsAttribute( - AvailableEndpointsAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, AVAILABLE_ENDPOINTS_ATTRIBUTE_ID); + public void writeStartUpModeAttribute(DefaultClusterCallback callback, Integer value) { + writeStartUpModeAttribute(callback, value, 0); + } + + public void writeStartUpModeAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType(); + writeAttribute(new WriteAttributesCallbackImpl(callback), START_UP_MODE_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeStartUpModeAttribute( + StartUpModeAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, START_UP_MODE_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, AVAILABLE_ENDPOINTS_ATTRIBUTE_ID, minInterval, maxInterval); + }, START_UP_MODE_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readActiveEndpointsAttribute( - ActiveEndpointsAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACTIVE_ENDPOINTS_ATTRIBUTE_ID); + public void readOnModeAttribute( + OnModeAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ON_MODE_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, ACTIVE_ENDPOINTS_ATTRIBUTE_ID, true); + }, ON_MODE_ATTRIBUTE_ID, true); } - public void subscribeActiveEndpointsAttribute( - ActiveEndpointsAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACTIVE_ENDPOINTS_ATTRIBUTE_ID); + public void writeOnModeAttribute(DefaultClusterCallback callback, Integer value) { + writeOnModeAttribute(callback, value, 0); + } + + public void writeOnModeAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType(); + writeAttribute(new WriteAttributesCallbackImpl(callback), ON_MODE_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeOnModeAttribute( + OnModeAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ON_MODE_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, ACTIVE_ENDPOINTS_ATTRIBUTE_ID, minInterval, maxInterval); + }, ON_MODE_ATTRIBUTE_ID, minInterval, maxInterval); } public void readGeneratedCommandListAttribute( @@ -33302,8 +34085,8 @@ public void onSuccess(byte[] tlv) { } } - public static class EnergyEvseModeCluster extends BaseChipCluster { - public static final long CLUSTER_ID = 157L; + public static class WaterHeaterModeCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 158L; private static final long SUPPORTED_MODES_ATTRIBUTE_ID = 0L; private static final long CURRENT_MODE_ATTRIBUTE_ID = 1L; @@ -33316,7 +34099,7 @@ public static class EnergyEvseModeCluster extends BaseChipCluster { private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L; private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L; - public EnergyEvseModeCluster(long devicePtr, int endpointId) { + public WaterHeaterModeCluster(long devicePtr, int endpointId) { super(devicePtr, endpointId, CLUSTER_ID); } @@ -33368,7 +34151,7 @@ public interface ChangeToModeResponseCallback extends BaseClusterCallback { } public interface SupportedModesAttributeCallback extends BaseAttributeCallback { - void onSuccess(List value); + void onSuccess(List value); } public interface StartUpModeAttributeCallback extends BaseAttributeCallback { @@ -33402,7 +34185,7 @@ public void readSupportedModesAttribute( 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); } }, SUPPORTED_MODES_ATTRIBUTE_ID, true); @@ -33415,7 +34198,7 @@ public void subscribeSupportedModesAttribute( 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); } }, SUPPORTED_MODES_ATTRIBUTE_ID, minInterval, maxInterval); @@ -53618,7 +54401,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 +54476,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 +54500,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 +60005,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 +60242,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 +60255,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 +60530,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 +60541,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 +60551,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 +60673,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/ChipStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java index 6cc21fd1f911c7..94bd7622678351 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java @@ -8608,6 +8608,143 @@ public String toString() { return output.toString(); } } +public static class WaterHeaterModeClusterModeTagStruct { + public Optional mfgCode; + public Integer value; + private static final long MFG_CODE_ID = 0L; + private static final long VALUE_ID = 1L; + + public WaterHeaterModeClusterModeTagStruct( + Optional mfgCode, + Integer value + ) { + this.mfgCode = mfgCode; + this.value = value; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(MFG_CODE_ID, mfgCode.map((nonOptionalmfgCode) -> new UIntType(nonOptionalmfgCode)).orElse(new EmptyType()))); + values.add(new StructElement(VALUE_ID, new UIntType(value))); + + return new StructType(values); + } + + public static WaterHeaterModeClusterModeTagStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Optional mfgCode = Optional.empty(); + Integer value = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == MFG_CODE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + mfgCode = Optional.of(castingValue.value(Integer.class)); + } + } else if (element.contextTagNum() == VALUE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + value = castingValue.value(Integer.class); + } + } + } + return new WaterHeaterModeClusterModeTagStruct( + mfgCode, + value + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("WaterHeaterModeClusterModeTagStruct {\n"); + output.append("\tmfgCode: "); + output.append(mfgCode); + output.append("\n"); + output.append("\tvalue: "); + output.append(value); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class WaterHeaterModeClusterModeOptionStruct { + public String label; + public Integer mode; + public ArrayList modeTags; + private static final long LABEL_ID = 0L; + private static final long MODE_ID = 1L; + private static final long MODE_TAGS_ID = 2L; + + public WaterHeaterModeClusterModeOptionStruct( + String label, + Integer mode, + ArrayList modeTags + ) { + this.label = label; + this.mode = mode; + this.modeTags = modeTags; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(LABEL_ID, new StringType(label))); + values.add(new StructElement(MODE_ID, new UIntType(mode))); + values.add(new StructElement(MODE_TAGS_ID, ArrayType.generateArrayType(modeTags, (elementmodeTags) -> elementmodeTags.encodeTlv()))); + + return new StructType(values); + } + + public static WaterHeaterModeClusterModeOptionStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + String label = null; + Integer mode = null; + ArrayList modeTags = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == LABEL_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + label = castingValue.value(String.class); + } + } else if (element.contextTagNum() == MODE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + mode = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == MODE_TAGS_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Array) { + ArrayType castingValue = element.value(ArrayType.class); + modeTags = castingValue.map((elementcastingValue) -> ChipStructs.WaterHeaterModeClusterModeTagStruct.decodeTlv(elementcastingValue)); + } + } + } + return new WaterHeaterModeClusterModeOptionStruct( + label, + mode, + modeTags + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("WaterHeaterModeClusterModeOptionStruct {\n"); + output.append("\tlabel: "); + output.append(label); + output.append("\n"); + output.append("\tmode: "); + output.append(mode); + output.append("\n"); + output.append("\tmodeTags: "); + output.append(modeTags); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} public static class DeviceEnergyManagementModeClusterModeTagStruct { public Optional mfgCode; public Integer value; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index eb51a558634fe4..b733ca22822c88 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(); } @@ -250,6 +253,9 @@ public static BaseCluster getCluster(long clusterId) { if (clusterId == EnergyEvseMode.ID) { return new EnergyEvseMode(); } + if (clusterId == WaterHeaterMode.ID) { + return new WaterHeaterMode(); + } if (clusterId == DeviceEnergyManagementMode.ID) { return new DeviceEnergyManagementMode(); } @@ -382,6 +388,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 +9309,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() { @@ -10344,6 +10478,128 @@ public long getCommandID(String name) throws IllegalArgumentException { return Command.valueOf(name).getID(); } } + public static class WaterHeaterMode implements BaseCluster { + public static final long ID = 158L; + public long getID() { + return ID; + } + + public enum Attribute { + SupportedModes(0L), + CurrentMode(1L), + StartUpMode(2L), + OnMode(3L), + 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 { + ChangeToMode(0L),; + 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 ChangeToModeCommandField {NewMode(0),; + private final int id; + ChangeToModeCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static ChangeToModeCommandField value(int id) throws NoSuchFieldError { + for (ChangeToModeCommandField field : ChangeToModeCommandField.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 DeviceEnergyManagementMode implements BaseCluster { public static final long ID = 159L; public long getID() { @@ -14565,7 +14821,7 @@ public enum Attribute { BorderAgentID(1L), ThreadVersion(2L), InterfaceEnabled(3L), - ActiveDatasetTimestamp(5L), + ActiveDatasetTimestamp(4L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), EventList(65530L), @@ -14614,8 +14870,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 +17166,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..23dc3048a5fb3d 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 @@ -11867,6 +11951,177 @@ public void onError(Exception ex) { } + public static class DelegatedWaterHeaterModeClusterChangeToModeResponseCallback implements ChipClusters.WaterHeaterModeCluster.ChangeToModeResponseCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(Integer status, Optional statusText) { + Map responseValues = new LinkedHashMap<>(); + + CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer"); + responseValues.put(statusResponseValue, status); + CommandResponseInfo statusTextResponseValue = new CommandResponseInfo("statusText", "Optional"); + responseValues.put(statusTextResponseValue, statusText); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } + public static class DelegatedWaterHeaterModeClusterSupportedModesAttributeCallback implements ChipClusters.WaterHeaterModeCluster.SupportedModesAttributeCallback, 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 DelegatedWaterHeaterModeClusterStartUpModeAttributeCallback implements ChipClusters.WaterHeaterModeCluster.StartUpModeAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable Integer value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWaterHeaterModeClusterOnModeAttributeCallback implements ChipClusters.WaterHeaterModeCluster.OnModeAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable Integer value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWaterHeaterModeClusterGeneratedCommandListAttributeCallback implements ChipClusters.WaterHeaterModeCluster.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 DelegatedWaterHeaterModeClusterAcceptedCommandListAttributeCallback implements ChipClusters.WaterHeaterModeCluster.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 DelegatedWaterHeaterModeClusterEventListAttributeCallback implements ChipClusters.WaterHeaterModeCluster.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 DelegatedWaterHeaterModeClusterAttributeListAttributeCallback implements ChipClusters.WaterHeaterModeCluster.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 DelegatedDeviceEnergyManagementModeClusterChangeToModeResponseCallback implements ChipClusters.DeviceEnergyManagementModeCluster.ChangeToModeResponseCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -19855,6 +20110,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 +22117,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); @@ -21776,6 +22149,10 @@ public Map initializeClusterMap() { (ptr, endpointId) -> new ChipClusters.EnergyEvseModeCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("energyEvseMode", energyEvseModeClusterInfo); + ClusterInfo waterHeaterModeClusterInfo = new ClusterInfo( + (ptr, endpointId) -> new ChipClusters.WaterHeaterModeCluster(ptr, endpointId), new HashMap<>()); + clusterMap.put("waterHeaterMode", waterHeaterModeClusterInfo); + ClusterInfo deviceEnergyManagementModeClusterInfo = new ClusterInfo( (ptr, endpointId) -> new ChipClusters.DeviceEnergyManagementModeCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("deviceEnergyManagementMode", deviceEnergyManagementModeClusterInfo); @@ -21952,6 +22329,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 +22420,7 @@ public void combineCommand(Map destination, 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(); @@ -25412,6 +25854,28 @@ public Map> getCommandMap() { commandMap.put("energyEvseMode", energyEvseModeClusterInteractionInfoMap); + Map waterHeaterModeClusterInteractionInfoMap = new LinkedHashMap<>(); + + Map waterHeaterModechangeToModeCommandParams = new LinkedHashMap(); + + CommandParameterInfo waterHeaterModechangeToModenewModeCommandParameterInfo = new CommandParameterInfo("newMode", Integer.class, Integer.class); + waterHeaterModechangeToModeCommandParams.put("newMode",waterHeaterModechangeToModenewModeCommandParameterInfo); + InteractionInfo waterHeaterModechangeToModeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster) + .changeToMode((ChipClusters.WaterHeaterModeCluster.ChangeToModeResponseCallback) callback + , (Integer) + commandArguments.get("newMode") + + ); + }, + () -> new DelegatedWaterHeaterModeClusterChangeToModeResponseCallback(), + waterHeaterModechangeToModeCommandParams + ); + waterHeaterModeClusterInteractionInfoMap.put("changeToMode", waterHeaterModechangeToModeInteractionInfo); + + commandMap.put("waterHeaterMode", waterHeaterModeClusterInteractionInfoMap); + Map deviceEnergyManagementModeClusterInteractionInfoMap = new LinkedHashMap<>(); Map deviceEnergyManagementModechangeToModeCommandParams = new LinkedHashMap(); @@ -28212,6 +28676,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..b6a359e031808b 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( @@ -10353,6 +10489,120 @@ private static Map readEnergyEvseModeInteractionInfo() return result; } + private static Map readWaterHeaterModeInteractionInfo() { + Map result = new LinkedHashMap<>();Map readWaterHeaterModeSupportedModesCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeSupportedModesAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readSupportedModesAttribute( + (ChipClusters.WaterHeaterModeCluster.SupportedModesAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterSupportedModesAttributeCallback(), + readWaterHeaterModeSupportedModesCommandParams + ); + result.put("readSupportedModesAttribute", readWaterHeaterModeSupportedModesAttributeInteractionInfo); + Map readWaterHeaterModeCurrentModeCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeCurrentModeAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readCurrentModeAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readWaterHeaterModeCurrentModeCommandParams + ); + result.put("readCurrentModeAttribute", readWaterHeaterModeCurrentModeAttributeInteractionInfo); + Map readWaterHeaterModeStartUpModeCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeStartUpModeAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readStartUpModeAttribute( + (ChipClusters.WaterHeaterModeCluster.StartUpModeAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterStartUpModeAttributeCallback(), + readWaterHeaterModeStartUpModeCommandParams + ); + result.put("readStartUpModeAttribute", readWaterHeaterModeStartUpModeAttributeInteractionInfo); + Map readWaterHeaterModeOnModeCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeOnModeAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readOnModeAttribute( + (ChipClusters.WaterHeaterModeCluster.OnModeAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterOnModeAttributeCallback(), + readWaterHeaterModeOnModeCommandParams + ); + result.put("readOnModeAttribute", readWaterHeaterModeOnModeAttributeInteractionInfo); + Map readWaterHeaterModeGeneratedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readGeneratedCommandListAttribute( + (ChipClusters.WaterHeaterModeCluster.GeneratedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterGeneratedCommandListAttributeCallback(), + readWaterHeaterModeGeneratedCommandListCommandParams + ); + result.put("readGeneratedCommandListAttribute", readWaterHeaterModeGeneratedCommandListAttributeInteractionInfo); + Map readWaterHeaterModeAcceptedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeAcceptedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readAcceptedCommandListAttribute( + (ChipClusters.WaterHeaterModeCluster.AcceptedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterAcceptedCommandListAttributeCallback(), + readWaterHeaterModeAcceptedCommandListCommandParams + ); + result.put("readAcceptedCommandListAttribute", readWaterHeaterModeAcceptedCommandListAttributeInteractionInfo); + Map readWaterHeaterModeEventListCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeEventListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readEventListAttribute( + (ChipClusters.WaterHeaterModeCluster.EventListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterEventListAttributeCallback(), + readWaterHeaterModeEventListCommandParams + ); + result.put("readEventListAttribute", readWaterHeaterModeEventListAttributeInteractionInfo); + Map readWaterHeaterModeAttributeListCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeAttributeListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readAttributeListAttribute( + (ChipClusters.WaterHeaterModeCluster.AttributeListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterAttributeListAttributeCallback(), + readWaterHeaterModeAttributeListCommandParams + ); + result.put("readAttributeListAttribute", readWaterHeaterModeAttributeListAttributeInteractionInfo); + Map readWaterHeaterModeFeatureMapCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeFeatureMapAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readFeatureMapAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readWaterHeaterModeFeatureMapCommandParams + ); + result.put("readFeatureMapAttribute", readWaterHeaterModeFeatureMapAttributeInteractionInfo); + Map readWaterHeaterModeClusterRevisionCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeClusterRevisionAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readClusterRevisionAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readWaterHeaterModeClusterRevisionCommandParams + ); + result.put("readClusterRevisionAttribute", readWaterHeaterModeClusterRevisionAttributeInteractionInfo); + + return result; + } private static Map readDeviceEnergyManagementModeInteractionInfo() { Map result = new LinkedHashMap<>();Map readDeviceEnergyManagementModeSupportedModesCommandParams = new LinkedHashMap(); InteractionInfo readDeviceEnergyManagementModeSupportedModesAttributeInteractionInfo = new InteractionInfo( @@ -18339,6 +18589,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 +21331,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()); @@ -21007,6 +21339,7 @@ public Map> getReadAttributeMap() { put("energyPreference", readEnergyPreferenceInteractionInfo()); put("powerTopology", readPowerTopologyInteractionInfo()); put("energyEvseMode", readEnergyEvseModeInteractionInfo()); + put("waterHeaterMode", readWaterHeaterModeInteractionInfo()); put("deviceEnergyManagementMode", readDeviceEnergyManagementModeInteractionInfo()); put("doorLock", readDoorLockInteractionInfo()); put("windowCovering", readWindowCoveringInteractionInfo()); @@ -21051,6 +21384,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..715cb477319345 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 = @@ -1406,6 +1408,52 @@ public Map> getWriteAttributeMap() { ); writeEnergyEvseModeInteractionInfo.put("writeOnModeAttribute", writeEnergyEvseModeOnModeAttributeInteractionInfo); writeAttributeMap.put("energyEvseMode", writeEnergyEvseModeInteractionInfo); + Map writeWaterHeaterModeInteractionInfo = new LinkedHashMap<>(); + Map writeWaterHeaterModeStartUpModeCommandParams = new LinkedHashMap(); + CommandParameterInfo waterHeaterModestartUpModeCommandParameterInfo = + new CommandParameterInfo( + "value", + Integer.class, + Integer.class + ); + writeWaterHeaterModeStartUpModeCommandParams.put( + "value", + waterHeaterModestartUpModeCommandParameterInfo + ); + InteractionInfo writeWaterHeaterModeStartUpModeAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).writeStartUpModeAttribute( + (DefaultClusterCallback) callback, + (Integer) commandArguments.get("value") + ); + }, + () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), + writeWaterHeaterModeStartUpModeCommandParams + ); + writeWaterHeaterModeInteractionInfo.put("writeStartUpModeAttribute", writeWaterHeaterModeStartUpModeAttributeInteractionInfo); + Map writeWaterHeaterModeOnModeCommandParams = new LinkedHashMap(); + CommandParameterInfo waterHeaterModeonModeCommandParameterInfo = + new CommandParameterInfo( + "value", + Integer.class, + Integer.class + ); + writeWaterHeaterModeOnModeCommandParams.put( + "value", + waterHeaterModeonModeCommandParameterInfo + ); + InteractionInfo writeWaterHeaterModeOnModeAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).writeOnModeAttribute( + (DefaultClusterCallback) callback, + (Integer) commandArguments.get("value") + ); + }, + () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), + writeWaterHeaterModeOnModeCommandParams + ); + writeWaterHeaterModeInteractionInfo.put("writeOnModeAttribute", writeWaterHeaterModeOnModeAttributeInteractionInfo); + writeAttributeMap.put("waterHeaterMode", writeWaterHeaterModeInteractionInfo); Map writeDeviceEnergyManagementModeInteractionInfo = new LinkedHashMap<>(); Map writeDeviceEnergyManagementModeStartUpModeCommandParams = new LinkedHashMap(); CommandParameterInfo deviceEnergyManagementModestartUpModeCommandParameterInfo = @@ -3716,6 +3764,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..c15fb2a01efd80 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni @@ -147,6 +147,8 @@ structs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestFabricScoped.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestListStructOctet.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UserLabelClusterLabelStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt", ] eventstructs_sources = [ @@ -163,6 +165,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/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt new file mode 100644 index 00000000000000..731c0395d7213d --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt @@ -0,0 +1,76 @@ +/* + * + * 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.structs + +import chip.devicecontroller.cluster.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WaterHeaterModeClusterModeOptionStruct( + val label: String, + val mode: UInt, + val modeTags: List, +) { + override fun toString(): String = buildString { + append("WaterHeaterModeClusterModeOptionStruct {\n") + append("\tlabel : $label\n") + append("\tmode : $mode\n") + append("\tmodeTags : $modeTags\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_LABEL), label) + put(ContextSpecificTag(TAG_MODE), mode) + startArray(ContextSpecificTag(TAG_MODE_TAGS)) + for (item in modeTags.iterator()) { + item.toTlv(AnonymousTag, this) + } + endArray() + endStructure() + } + } + + companion object { + private const val TAG_LABEL = 0 + private const val TAG_MODE = 1 + private const val TAG_MODE_TAGS = 2 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): WaterHeaterModeClusterModeOptionStruct { + tlvReader.enterStructure(tlvTag) + val label = tlvReader.getString(ContextSpecificTag(TAG_LABEL)) + val mode = tlvReader.getUInt(ContextSpecificTag(TAG_MODE)) + val modeTags = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_MODE_TAGS)) + while (!tlvReader.isEndOfContainer()) { + add(WaterHeaterModeClusterModeTagStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + tlvReader.exitContainer() + + return WaterHeaterModeClusterModeOptionStruct(label, mode, modeTags) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt new file mode 100644 index 00000000000000..52281b378efc57 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt @@ -0,0 +1,65 @@ +/* + * + * 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.structs + +import chip.devicecontroller.cluster.* +import java.util.Optional +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WaterHeaterModeClusterModeTagStruct(val mfgCode: Optional, val value: UInt) { + override fun toString(): String = buildString { + append("WaterHeaterModeClusterModeTagStruct {\n") + append("\tmfgCode : $mfgCode\n") + append("\tvalue : $value\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + if (mfgCode.isPresent) { + val optmfgCode = mfgCode.get() + put(ContextSpecificTag(TAG_MFG_CODE), optmfgCode) + } + put(ContextSpecificTag(TAG_VALUE), value) + endStructure() + } + } + + companion object { + private const val TAG_MFG_CODE = 0 + private const val TAG_VALUE = 1 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): WaterHeaterModeClusterModeTagStruct { + tlvReader.enterStructure(tlvTag) + val mfgCode = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_MFG_CODE))) { + Optional.of(tlvReader.getUInt(ContextSpecificTag(TAG_MFG_CODE))) + } else { + Optional.empty() + } + val value = tlvReader.getUInt(ContextSpecificTag(TAG_VALUE)) + + tlvReader.exitContainer() + + return WaterHeaterModeClusterModeTagStruct(mfgCode, value) + } + } +} 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/clusters/WaterHeaterModeCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterModeCluster.kt new file mode 100644 index 00000000000000..27352644935c8a --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterModeCluster.kt @@ -0,0 +1,1199 @@ +/* + * + * 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.UByteSubscriptionState +import matter.controller.UIntSubscriptionState +import matter.controller.UShortSubscriptionState +import matter.controller.WriteRequest +import matter.controller.WriteRequests +import matter.controller.WriteResponse +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 WaterHeaterModeCluster( + private val controller: MatterController, + private val endpointId: UShort, +) { + class ChangeToModeResponse(val status: UByte, val statusText: String?) + + class SupportedModesAttribute(val value: List) + + sealed class SupportedModesAttributeSubscriptionState { + data class Success(val value: List) : + SupportedModesAttributeSubscriptionState() + + data class Error(val exception: Exception) : SupportedModesAttributeSubscriptionState() + + object SubscriptionEstablished : SupportedModesAttributeSubscriptionState() + } + + class StartUpModeAttribute(val value: UByte?) + + sealed class StartUpModeAttributeSubscriptionState { + data class Success(val value: UByte?) : StartUpModeAttributeSubscriptionState() + + data class Error(val exception: Exception) : StartUpModeAttributeSubscriptionState() + + object SubscriptionEstablished : StartUpModeAttributeSubscriptionState() + } + + class OnModeAttribute(val value: UByte?) + + sealed class OnModeAttributeSubscriptionState { + data class Success(val value: UByte?) : OnModeAttributeSubscriptionState() + + data class Error(val exception: Exception) : OnModeAttributeSubscriptionState() + + object SubscriptionEstablished : OnModeAttributeSubscriptionState() + } + + 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 changeToMode( + newMode: UByte, + timedInvokeTimeout: Duration? = null, + ): ChangeToModeResponse { + val commandId: UInt = 0u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NEW_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_NEW_MODE_REQ), newMode) + 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_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_STATUS_TEXT: Int = 1 + var statusText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_STATUS_TEXT)) { + statusText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + tlvReader.skipElement() + } + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } + + tlvReader.exitContainer() + + return ChangeToModeResponse(status_decoded, statusText_decoded) + } + + suspend fun readSupportedModesAttribute(): SupportedModesAttribute { + 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) { "Supportedmodes 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(WaterHeaterModeClusterModeOptionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return SupportedModesAttribute(decodedValue) + } + + suspend fun subscribeSupportedModesAttribute( + 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( + SupportedModesAttributeSubscriptionState.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) { + "Supportedmodes 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(WaterHeaterModeClusterModeOptionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + emit(SupportedModesAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(SupportedModesAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readCurrentModeAttribute(): 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) { "Currentmode 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 subscribeCurrentModeAttribute( + 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) { "Currentmode 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 readStartUpModeAttribute(): StartUpModeAttribute { + 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) { "Startupmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return StartUpModeAttribute(decodedValue) + } + + suspend fun writeStartUpModeAttribute(value: UByte, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 2u + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded(), + ) + ), + timedRequest = timedWriteTimeout, + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun subscribeStartUpModeAttribute( + 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( + StartUpModeAttributeSubscriptionState.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) { "Startupmode 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.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(StartUpModeAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(StartUpModeAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readOnModeAttribute(): OnModeAttribute { + 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) { "Onmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OnModeAttribute(decodedValue) + } + + suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 3u + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded(), + ) + ), + timedRequest = timedWriteTimeout, + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun subscribeOnModeAttribute( + 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( + OnModeAttributeSubscriptionState.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) { "Onmode 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.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(OnModeAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(OnModeAttributeSubscriptionState.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(WaterHeaterModeCluster::class.java.name) + const val CLUSTER_ID: UInt = 158u + } +} 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..bf7839d661528d 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/files.gni +++ b/src/controller/java/generated/java/matter/controller/cluster/files.gni @@ -147,6 +147,8 @@ matter_structs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestFabricScoped.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestListStructOctet.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UserLabelClusterLabelStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt", ] matter_eventstructs_sources = [ @@ -163,6 +165,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 +257,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 +356,8 @@ 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/WaterHeaterModeCluster.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/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt new file mode 100644 index 00000000000000..52252bf6e4cc56 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt @@ -0,0 +1,76 @@ +/* + * + * 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.structs + +import matter.controller.cluster.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WaterHeaterModeClusterModeOptionStruct( + val label: String, + val mode: UByte, + val modeTags: List, +) { + override fun toString(): String = buildString { + append("WaterHeaterModeClusterModeOptionStruct {\n") + append("\tlabel : $label\n") + append("\tmode : $mode\n") + append("\tmodeTags : $modeTags\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_LABEL), label) + put(ContextSpecificTag(TAG_MODE), mode) + startArray(ContextSpecificTag(TAG_MODE_TAGS)) + for (item in modeTags.iterator()) { + item.toTlv(AnonymousTag, this) + } + endArray() + endStructure() + } + } + + companion object { + private const val TAG_LABEL = 0 + private const val TAG_MODE = 1 + private const val TAG_MODE_TAGS = 2 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): WaterHeaterModeClusterModeOptionStruct { + tlvReader.enterStructure(tlvTag) + val label = tlvReader.getString(ContextSpecificTag(TAG_LABEL)) + val mode = tlvReader.getUByte(ContextSpecificTag(TAG_MODE)) + val modeTags = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_MODE_TAGS)) + while (!tlvReader.isEndOfContainer()) { + add(WaterHeaterModeClusterModeTagStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + tlvReader.exitContainer() + + return WaterHeaterModeClusterModeOptionStruct(label, mode, modeTags) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt new file mode 100644 index 00000000000000..fc91c1389574ab --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt @@ -0,0 +1,65 @@ +/* + * + * 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.structs + +import java.util.Optional +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WaterHeaterModeClusterModeTagStruct(val mfgCode: Optional, val value: UShort) { + override fun toString(): String = buildString { + append("WaterHeaterModeClusterModeTagStruct {\n") + append("\tmfgCode : $mfgCode\n") + append("\tvalue : $value\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + if (mfgCode.isPresent) { + val optmfgCode = mfgCode.get() + put(ContextSpecificTag(TAG_MFG_CODE), optmfgCode) + } + put(ContextSpecificTag(TAG_VALUE), value) + endStructure() + } + } + + companion object { + private const val TAG_MFG_CODE = 0 + private const val TAG_VALUE = 1 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): WaterHeaterModeClusterModeTagStruct { + tlvReader.enterStructure(tlvTag) + val mfgCode = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_MFG_CODE))) { + Optional.of(tlvReader.getUShort(ContextSpecificTag(TAG_MFG_CODE))) + } else { + Optional.empty() + } + val value = tlvReader.getUShort(ContextSpecificTag(TAG_VALUE)) + + tlvReader.exitContainer() + + return WaterHeaterModeClusterModeTagStruct(mfgCode, value) + } + } +} diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index 66797f78118dd1..9d1d0bd1bb65a3 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) @@ -25100,38 +25338,363 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR 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); + 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::PowerTopology::Id: { + using namespace app::Clusters::PowerTopology; + switch (aPath.mAttributeId) + { + case Attributes::AvailableEndpoints::Id: { + using TypeInfo = Attributes::AvailableEndpoints::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/Integer"; + std::string newElement_0CtorSignature = "(I)V"; + jint 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::ActiveEndpoints::Id: { + using TypeInfo = Attributes::ActiveEndpoints::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/Integer"; + std::string newElement_0CtorSignature = "(I)V"; + jint 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::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::EnergyEvseMode::Id: { + using namespace app::Clusters::EnergyEvseMode; + switch (aPath.mAttributeId) + { + case Attributes::SupportedModes::Id: { + using TypeInfo = Attributes::SupportedModes::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; + jobject newElement_0_label; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.label, newElement_0_label)); + jobject newElement_0_mode; + std::string newElement_0_modeClassName = "java/lang/Integer"; + std::string newElement_0_modeCtorSignature = "(I)V"; + jint jninewElement_0_mode = static_cast(entry_0.mode); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_modeClassName.c_str(), + newElement_0_modeCtorSignature.c_str(), + jninewElement_0_mode, newElement_0_mode); + jobject newElement_0_modeTags; + chip::JniReferences::GetInstance().CreateArrayList(newElement_0_modeTags); + + auto iter_newElement_0_modeTags_2 = entry_0.modeTags.begin(); + while (iter_newElement_0_modeTags_2.Next()) + { + auto & entry_2 = iter_newElement_0_modeTags_2.GetValue(); + jobject newElement_2; + jobject newElement_2_mfgCode; + if (!entry_2.mfgCode.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_2_mfgCode); + } + else + { + jobject newElement_2_mfgCodeInsideOptional; + std::string newElement_2_mfgCodeInsideOptionalClassName = "java/lang/Integer"; + std::string newElement_2_mfgCodeInsideOptionalCtorSignature = "(I)V"; + jint jninewElement_2_mfgCodeInsideOptional = static_cast(entry_2.mfgCode.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_2_mfgCodeInsideOptionalClassName.c_str(), + newElement_2_mfgCodeInsideOptionalCtorSignature.c_str(), jninewElement_2_mfgCodeInsideOptional, + newElement_2_mfgCodeInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(newElement_2_mfgCodeInsideOptional, newElement_2_mfgCode); + } + jobject newElement_2_value; + std::string newElement_2_valueClassName = "java/lang/Integer"; + std::string newElement_2_valueCtorSignature = "(I)V"; + jint jninewElement_2_value = static_cast(entry_2.value); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_2_valueClassName.c_str(), + newElement_2_valueCtorSignature.c_str(), + jninewElement_2_value, newElement_2_value); + + jclass modeTagStructStructClass_3; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$EnergyEvseModeClusterModeTagStruct", modeTagStructStructClass_3); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$EnergyEvseModeClusterModeTagStruct"); + return nullptr; + } + + jmethodID modeTagStructStructCtor_3; + err = chip::JniReferences::GetInstance().FindMethod(env, modeTagStructStructClass_3, "", + "(Ljava/util/Optional;Ljava/lang/Integer;)V", + &modeTagStructStructCtor_3); + if (err != CHIP_NO_ERROR || modeTagStructStructCtor_3 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$EnergyEvseModeClusterModeTagStruct constructor"); + return nullptr; + } + + newElement_2 = env->NewObject(modeTagStructStructClass_3, modeTagStructStructCtor_3, newElement_2_mfgCode, + newElement_2_value); + chip::JniReferences::GetInstance().AddToList(newElement_0_modeTags, newElement_2); + } + + jclass modeOptionStructStructClass_1; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$EnergyEvseModeClusterModeOptionStruct", modeOptionStructStructClass_1); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$EnergyEvseModeClusterModeOptionStruct"); + return nullptr; + } + + jmethodID modeOptionStructStructCtor_1; + err = chip::JniReferences::GetInstance().FindMethod(env, modeOptionStructStructClass_1, "", + "(Ljava/lang/String;Ljava/lang/Integer;Ljava/util/ArrayList;)V", + &modeOptionStructStructCtor_1); + if (err != CHIP_NO_ERROR || modeOptionStructStructCtor_1 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$EnergyEvseModeClusterModeOptionStruct constructor"); + return nullptr; + } + + newElement_0 = env->NewObject(modeOptionStructStructClass_1, modeOptionStructStructCtor_1, newElement_0_label, + newElement_0_mode, newElement_0_modeTags); 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; + case Attributes::CurrentMode::Id: { + using TypeInfo = Attributes::CurrentMode::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -25146,18 +25709,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR value); return value; } - default: - *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; - break; - } - break; - } - case app::Clusters::PowerTopology::Id: { - using namespace app::Clusters::PowerTopology; - switch (aPath.mAttributeId) - { - case Attributes::AvailableEndpoints::Id: { - using TypeInfo = Attributes::AvailableEndpoints::TypeInfo; + case Attributes::StartUpMode::Id: { + using TypeInfo = Attributes::StartUpMode::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -25165,24 +25718,22 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR return nullptr; } jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) + if (cppValue.IsNull()) { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Integer"; - std::string newElement_0CtorSignature = "(I)V"; - jint 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); + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); } return value; } - case Attributes::ActiveEndpoints::Id: { - using TypeInfo = Attributes::ActiveEndpoints::TypeInfo; + case Attributes::OnMode::Id: { + using TypeInfo = Attributes::OnMode::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -25190,19 +25741,17 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR return nullptr; } jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) + if (cppValue.IsNull()) { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Integer"; - std::string newElement_0CtorSignature = "(I)V"; - jint 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); + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); } return value; } @@ -25344,8 +25893,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } - case app::Clusters::EnergyEvseMode::Id: { - using namespace app::Clusters::EnergyEvseMode; + case app::Clusters::WaterHeaterMode::Id: { + using namespace app::Clusters::WaterHeaterMode; switch (aPath.mAttributeId) { case Attributes::SupportedModes::Id: { @@ -25408,10 +25957,10 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR jclass modeTagStructStructClass_3; err = chip::JniReferences::GetInstance().GetLocalClassRef( - env, "chip/devicecontroller/ChipStructs$EnergyEvseModeClusterModeTagStruct", modeTagStructStructClass_3); + env, "chip/devicecontroller/ChipStructs$WaterHeaterModeClusterModeTagStruct", modeTagStructStructClass_3); if (err != CHIP_NO_ERROR) { - ChipLogError(Zcl, "Could not find class ChipStructs$EnergyEvseModeClusterModeTagStruct"); + ChipLogError(Zcl, "Could not find class ChipStructs$WaterHeaterModeClusterModeTagStruct"); return nullptr; } @@ -25421,7 +25970,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR &modeTagStructStructCtor_3); if (err != CHIP_NO_ERROR || modeTagStructStructCtor_3 == nullptr) { - ChipLogError(Zcl, "Could not find ChipStructs$EnergyEvseModeClusterModeTagStruct constructor"); + ChipLogError(Zcl, "Could not find ChipStructs$WaterHeaterModeClusterModeTagStruct constructor"); return nullptr; } @@ -25432,10 +25981,10 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR jclass modeOptionStructStructClass_1; err = chip::JniReferences::GetInstance().GetLocalClassRef( - env, "chip/devicecontroller/ChipStructs$EnergyEvseModeClusterModeOptionStruct", modeOptionStructStructClass_1); + env, "chip/devicecontroller/ChipStructs$WaterHeaterModeClusterModeOptionStruct", modeOptionStructStructClass_1); if (err != CHIP_NO_ERROR) { - ChipLogError(Zcl, "Could not find class ChipStructs$EnergyEvseModeClusterModeOptionStruct"); + ChipLogError(Zcl, "Could not find class ChipStructs$WaterHeaterModeClusterModeOptionStruct"); return nullptr; } @@ -25445,7 +25994,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR &modeOptionStructStructCtor_1); if (err != CHIP_NO_ERROR || modeOptionStructStructCtor_1 == nullptr) { - ChipLogError(Zcl, "Could not find ChipStructs$EnergyEvseModeClusterModeOptionStruct constructor"); + ChipLogError(Zcl, "Could not find ChipStructs$WaterHeaterModeClusterModeOptionStruct constructor"); return nullptr; } @@ -42162,6 +42711,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..789e3ea5f1310e 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; } @@ -6086,6 +6134,16 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } break; } + case app::Clusters::WaterHeaterMode::Id: { + using namespace app::Clusters::WaterHeaterMode; + switch (aPath.mEventId) + { + default: + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + break; + } + break; + } case app::Clusters::DeviceEnergyManagementMode::Id: { using namespace app::Clusters::DeviceEnergyManagementMode; switch (aPath.mEventId) @@ -7920,6 +7978,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/CertificateAuthority.py b/src/controller/python/chip/CertificateAuthority.py index bce921cfb785bf..0fbfcfdbdb93b8 100644 --- a/src/controller/python/chip/CertificateAuthority.py +++ b/src/controller/python/chip/CertificateAuthority.py @@ -28,6 +28,8 @@ from chip.native import PyChipError from chip.storage import PersistentStorage +LOGGER = logging.getLogger(__name__) + class CertificateAuthority: ''' This represents an operational Root Certificate Authority (CA) with a root key key pair with associated @@ -64,7 +66,7 @@ def __init__(self, chipStack: ChipStack.ChipStack, caIndex: int, persistentStora persistentStorage: An optional reference to a PersistentStorage object. If one is provided, it will pick that over the default PersistentStorage object retrieved from the chipStack. ''' - self.logger().warning(f"New CertificateAuthority at index {caIndex}") + LOGGER.info(f"New CertificateAuthority at index {caIndex}") self._chipStack = chipStack self._caIndex = caIndex @@ -105,7 +107,7 @@ def LoadFabricAdminsFromStorage(self): if (not (self._isActive)): raise RuntimeError("Object isn't active") - self.logger().warning("Loading fabric admins from storage...") + LOGGER.info("Loading fabric admins from storage...") caList = self._persistentStorage.GetReplKey(key='caList') if (str(self._caIndex) not in caList): @@ -244,7 +246,7 @@ def LoadAuthoritiesFromStorage(self): if (not (self._isActive)): raise RuntimeError("Object is not active") - self.logger().warning("Loading certificate authorities from storage...") + LOGGER.info("Loading certificate authorities from storage...") # # Persist details to storage (read modify write). diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index efadd7fd4f87c7..4e1c5d6678ed3e 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -61,6 +61,8 @@ # Defined in $CHIP_ROOT/src/lib/core/CHIPError.h CHIP_ERROR_TIMEOUT: int = 50 +LOGGER = logging.getLogger(__name__) + _DevicePairingDelegate_OnPairingCompleteFunct = CFUNCTYPE(None, PyChipError) _DeviceUnpairingCompleteFunct = CFUNCTYPE(None, c_uint64, PyChipError) _DevicePairingDelegate_OnCommissioningCompleteFunct = CFUNCTYPE( @@ -247,7 +249,10 @@ def future(self) -> typing.Optional[concurrent.futures.Future]: async def __aexit__(self, exc_type, exc_value, traceback): if not self._future.done(): - raise RuntimeError("CallbackContext future not completed") + # In case the initial call (which sets up for the callback) fails, + # the future will never be used actually. So just cancel it here + # for completeness, in case somebody is expecting it to be completed. + self._future.cancel() self._future = None self._lock.release() @@ -401,9 +406,9 @@ def __init__(self, name: str = ''): def _set_dev_ctrl(self, devCtrl, pairingDelegate): def HandleCommissioningComplete(nodeId: int, err: PyChipError): if err.is_success: - logging.info("Commissioning complete") + LOGGER.info("Commissioning complete") else: - logging.warning("Failed to commission: {}".format(err)) + LOGGER.warning("Failed to commission: {}".format(err)) self._dmLib.pychip_DeviceController_SetIcdRegistrationParameters(False, None) @@ -411,7 +416,7 @@ def HandleCommissioningComplete(nodeId: int, err: PyChipError): err = self._dmLib.pychip_GetCompletionError() if self._commissioning_context.future is None: - logging.exception("HandleCommissioningComplete called unexpectedly") + LOGGER.exception("HandleCommissioningComplete called unexpectedly") return if err.is_success: @@ -425,14 +430,14 @@ def HandleFabricCheck(nodeId): def HandleOpenWindowComplete(nodeid: int, setupPinCode: int, setupManualCode: str, setupQRCode: str, err: PyChipError) -> None: if err.is_success: - logging.info("Open Commissioning Window complete setting nodeid {} pincode to {}".format(nodeid, setupPinCode)) + LOGGER.info("Open Commissioning Window complete setting nodeid {} pincode to {}".format(nodeid, setupPinCode)) commissioningParameters = CommissioningParameters( setupPinCode=setupPinCode, setupManualCode=setupManualCode.decode(), setupQRCode=setupQRCode.decode()) else: - logging.warning("Failed to open commissioning window: {}".format(err)) + LOGGER.warning("Failed to open commissioning window: {}".format(err)) if self._open_window_context.future is None: - logging.exception("HandleOpenWindowComplete called unexpectedly") + LOGGER.exception("HandleOpenWindowComplete called unexpectedly") return if err.is_success: @@ -442,12 +447,12 @@ def HandleOpenWindowComplete(nodeid: int, setupPinCode: int, setupManualCode: st def HandleUnpairDeviceComplete(nodeid: int, err: PyChipError): if err.is_success: - logging.info("Succesfully unpaired device with nodeid {}".format(nodeid)) + LOGGER.info("Succesfully unpaired device with nodeid {}".format(nodeid)) else: - logging.warning("Failed to unpair device: {}".format(err)) + LOGGER.warning("Failed to unpair device: {}".format(err)) if self._unpair_device_context.future is None: - logging.exception("HandleUnpairDeviceComplete called unexpectedly") + LOGGER.exception("HandleUnpairDeviceComplete called unexpectedly") return if err.is_success: @@ -457,9 +462,9 @@ def HandleUnpairDeviceComplete(nodeid: int, err: PyChipError): def HandlePASEEstablishmentComplete(err: PyChipError): if not err.is_success: - logging.warning("Failed to establish secure session to device: {}".format(err)) + LOGGER.warning("Failed to establish secure session to device: {}".format(err)) else: - logging.info("Established secure session with Device") + LOGGER.info("Established secure session with Device") if self._commissioning_context.future is not None: # During Commissioning, HandlePASEEstablishmentComplete will also be called. @@ -469,7 +474,7 @@ def HandlePASEEstablishmentComplete(err: PyChipError): return if self._pase_establishment_context.future is None: - logging.exception("HandlePASEEstablishmentComplete called unexpectedly") + LOGGER.exception("HandlePASEEstablishmentComplete called unexpectedly") return if err.is_success: @@ -601,11 +606,10 @@ async def ConnectBLE(self, discriminator: int, setupPinCode: int, nodeid: int, i async with self._commissioning_context as ctx: self._enablePairingCompleteCallback(True) - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectBLE( self.devCtrl, discriminator, isShortDiscriminator, setupPinCode, nodeid) ) - res.raise_on_error() return await asyncio.futures.wrap_future(ctx.future) @@ -613,11 +617,11 @@ async def UnpairDevice(self, nodeid: int) -> None: self.CheckIsActive() async with self._unpair_device_context as ctx: - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_UnpairDevice( self.devCtrl, nodeid, self.cbHandleDeviceUnpairCompleteFunct) ) - res.raise_on_error() + return await asyncio.futures.wrap_future(ctx.future) def CloseBLEConnection(self): @@ -654,8 +658,7 @@ async def _establishPASESession(self, callFunct): async with self._pase_establishment_context as ctx: self._enablePairingCompleteCallback(True) - res = await self._ChipStack.CallAsync(callFunct) - res.raise_on_error() + await self._ChipStack.CallAsync(callFunct) await asyncio.futures.wrap_future(ctx.future) async def EstablishPASESessionBLE(self, setupPinCode: int, discriminator: int, nodeid: int) -> None: @@ -754,13 +757,12 @@ async def DiscoverCommissionableNodes(self, filterType: discovery.FilterType = d # Discovery is also used during commissioning. Make sure this manual discovery # and commissioning attempts do not interfere with each other. async with self._commissioning_lock: - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_DiscoverCommissionableNodes( self.devCtrl, int(filterType), str(filter).encode("utf-8"))) - res.raise_on_error() async def _wait_discovery(): - while not await self._ChipStack.CallAsync( + while not await self._ChipStack.CallAsyncWithResult( lambda: self._dmLib.pychip_DeviceController_HasDiscoveredCommissionableNode(self.devCtrl)): await asyncio.sleep(0.1) return @@ -774,9 +776,8 @@ async def _wait_discovery(): # Expected timeout, do nothing pass finally: - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_StopCommissionableDiscovery(self.devCtrl)) - res.raise_on_error() return await self.GetDiscoveredDevices() @@ -794,7 +795,7 @@ def HandleDevice(deviceJson, deviceJsonLen): self._dmLib.pychip_DeviceController_IterateDiscoveredCommissionableNodes(devCtrl.devCtrl, HandleDevice) return devices - return await self._ChipStack.CallAsync(lambda: GetDevices(self)) + return await self._ChipStack.CallAsyncWithResult(lambda: GetDevices(self)) def GetIPForDiscoveredDevice(self, idx, addrStr, length): self.CheckIsActive() @@ -826,11 +827,10 @@ async def OpenCommissioningWindow(self, nodeid: int, timeout: int, iteration: in self.CheckIsActive() async with self._open_window_context as ctx: - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_OpenCommissioningWindow( self.devCtrl, self.pairingDelegate, nodeid, timeout, iteration, discriminator, option) ) - res.raise_on_error() return await asyncio.futures.wrap_future(ctx.future) @@ -894,14 +894,14 @@ async def FindOrEstablishPASESession(self, setupCode: str, nodeid: int, timeoutM ''' Returns CommissioneeDeviceProxy if we can find or establish a PASE connection to the specified device''' self.CheckIsActive() returnDevice = c_void_p(None) - res = await self._ChipStack.CallAsync(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( + res = await self._ChipStack.CallAsyncWithResult(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( self.devCtrl, nodeid, byref(returnDevice)), timeoutMs) if res.is_success: return DeviceProxyWrapper(returnDevice, DeviceProxyWrapper.DeviceProxyType.COMMISSIONEE, self._dmLib) await self.EstablishPASESession(setupCode, nodeid) - res = await self._ChipStack.CallAsync(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( + res = await self._ChipStack.CallAsyncWithResult(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( self.devCtrl, nodeid, byref(returnDevice)), timeoutMs) if res.is_success: return DeviceProxyWrapper(returnDevice, DeviceProxyWrapper.DeviceProxyType.COMMISSIONEE, self._dmLib) @@ -926,7 +926,7 @@ def GetConnectedDeviceSync(self, nodeid, allowPASE=True, timeoutMs: int = None): res = self._ChipStack.Call(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( self.devCtrl, nodeid, byref(returnDevice)), timeoutMs) if res.is_success: - logging.info('Using PASE connection') + LOGGER.info('Using PASE connection') return DeviceProxyWrapper(returnDevice, DeviceProxyWrapper.DeviceProxyType.COMMISSIONEE, self._dmLib) class DeviceAvailableClosure(): @@ -989,10 +989,10 @@ async def GetConnectedDevice(self, nodeid, allowPASE: bool = True, timeoutMs: in if allowPASE: returnDevice = c_void_p(None) - res = await self._ChipStack.CallAsync(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( + res = await self._ChipStack.CallAsyncWithResult(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( self.devCtrl, nodeid, byref(returnDevice)), timeoutMs) if res.is_success: - logging.info('Using PASE connection') + LOGGER.info('Using PASE connection') return DeviceProxyWrapper(returnDevice, DeviceProxyWrapper.DeviceProxyType.COMMISSIONEE, self._dmLib) eventLoop = asyncio.get_running_loop() @@ -1019,10 +1019,9 @@ def deviceAvailable(self, device, err): closure = DeviceAvailableClosure(eventLoop, future) ctypes.pythonapi.Py_IncRef(ctypes.py_object(closure)) - res = await self._ChipStack.CallAsync(lambda: self._dmLib.pychip_GetConnectedDeviceByNodeId( + await self._ChipStack.CallAsync(lambda: self._dmLib.pychip_GetConnectedDeviceByNodeId( self.devCtrl, nodeid, ctypes.py_object(closure), _DeviceAvailableCallback), timeoutMs) - res.raise_on_error() # The callback might have been received synchronously (during self._ChipStack.CallAsync()). # In that case the Future has already been set it will return immediately @@ -1348,7 +1347,6 @@ def _parseEventPathTuple(self, pathTuple: typing.Union[ # Wildcard return ClusterAttribute.EventPath() elif not isinstance(pathTuple, tuple): - logging.debug(type(pathTuple)) if isinstance(pathTuple, int): return ClusterAttribute.EventPath(EndpointId=pathTuple) elif issubclass(pathTuple, ClusterObjects.Cluster): @@ -1438,6 +1436,13 @@ async def Read(self, nodeid: int, attributes: typing.List[typing.Union[ reportInterval: A tuple of two int-s for (MinIntervalFloor, MaxIntervalCeiling). Used by establishing subscriptions. When not provided, a read request will be sent. + fabricFiltered: If True (default), the read/subscribe is fabric-filtered and will only see things associated with the fabric + of the reader/subscriber. Relevant for attributes with fabric-scoped data. + keepSubscriptions: Keep existing subscriptions. If set to False, existing subscriptions with this node will get cancelled + and a new one gets setup. + autoResubscribe: Automatically resubscribe to the subscription if subscription is lost. The automatic re-subscription only + applies if the subscription establishes on first try. If the first subscription establishment attempt fails the function + returns right away. Returns: - AsyncReadTransaction.ReadResponse. Please see ReadAttribute and ReadEvent for examples of how to access data. @@ -1507,6 +1512,13 @@ async def ReadAttribute(self, nodeid: int, attributes: typing.List[typing.Union[ reportInterval: A tuple of two int-s for (MinIntervalFloor, MaxIntervalCeiling). Used by establishing subscriptions. When not provided, a read request will be sent. + fabricFiltered: If True (default), the read/subscribe is fabric-filtered and will only see things associated with the fabric + of the reader/subscriber. Relevant for attributes with fabric-scoped data. + keepSubscriptions: Keep existing subscriptions. If set to False, existing subscriptions with this node will get cancelled + and a new one gets setup. + autoResubscribe: Automatically resubscribe to the subscription if subscription is lost. The automatic re-subscription only + applies if the subscription establishes on first try. If the first subscription establishment attempt fails the function + returns right away. Returns: - subscription request: ClusterAttribute.SubscriptionTransaction @@ -1583,6 +1595,11 @@ async def ReadEvent(self, nodeid: int, events: typing.List[typing.Union[ eventNumberFilter: Optional minimum event number filter. reportInterval: A tuple of two int-s for (MinIntervalFloor, MaxIntervalCeiling). Used by establishing subscriptions. When not provided, a read request will be sent. + keepSubscriptions: Keep existing subscriptions. If set to False, existing subscriptions with this node will get cancelled + and a new one gets setup. + autoResubscribe: Automatically resubscribe to the subscription if subscription is lost. The automatic re-subscription only + applies if the subscription establishes on first try. If the first subscription establishment attempt fails the function + returns right away. Returns: - subscription request: ClusterAttribute.SubscriptionTransaction @@ -1916,11 +1933,10 @@ async def Commission(self, nodeid) -> int: async with self._commissioning_context as ctx: self._enablePairingCompleteCallback(False) - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_Commission( self.devCtrl, nodeid) ) - res.raise_on_error() return await asyncio.futures.wrap_future(ctx.future) @@ -2064,11 +2080,10 @@ async def CommissionOnNetwork(self, nodeId: int, setupPinCode: int, async with self._commissioning_context as ctx: self._enablePairingCompleteCallback(True) - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_OnNetworkCommission( self.devCtrl, self.pairingDelegate, nodeId, setupPinCode, int(filterType), str(filter).encode("utf-8") if filter is not None else None, discoveryTimeoutMsec) ) - res.raise_on_error() return await asyncio.futures.wrap_future(ctx.future) @@ -2085,11 +2100,10 @@ async def CommissionWithCode(self, setupPayload: str, nodeid: int, discoveryType async with self._commissioning_context as ctx: self._enablePairingCompleteCallback(True) - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectWithCode( self.devCtrl, setupPayload.encode("utf-8"), nodeid, discoveryType.value) ) - res.raise_on_error() return await asyncio.futures.wrap_future(ctx.future) @@ -2105,17 +2119,16 @@ async def CommissionIP(self, ipaddr: str, setupPinCode: int, nodeid: int) -> int async with self._commissioning_context as ctx: self._enablePairingCompleteCallback(True) - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectIP( self.devCtrl, ipaddr.encode("utf-8"), setupPinCode, nodeid) ) - res.raise_on_error() return await asyncio.futures.wrap_future(ctx.future) def NOCChainCallback(self, nocChain): if self._issue_node_chain_context.future is None: - logging.exception("NOCChainCallback while not expecting a callback") + LOGGER.exception("NOCChainCallback while not expecting a callback") return self._issue_node_chain_context.future.set_result(nocChain) return @@ -2126,11 +2139,11 @@ async def IssueNOCChain(self, csr: Clusters.OperationalCredentials.Commands.CSRR self.CheckIsActive() async with self._issue_node_chain_context as ctx: - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_IssueNOCChain( self.devCtrl, py_object(self), csr.NOCSRElements, len(csr.NOCSRElements), nodeId) ) - res.raise_on_error() + return await asyncio.futures.wrap_future(ctx.future) diff --git a/src/controller/python/chip/ChipStack.py b/src/controller/python/chip/ChipStack.py index dc4efc223f491d..b717859c70351d 100644 --- a/src/controller/python/chip/ChipStack.py +++ b/src/controller/python/chip/ChipStack.py @@ -216,7 +216,7 @@ def Call(self, callFunct, timeoutMs: int = None): ''' return self.PostTaskOnChipThread(callFunct).Wait(timeoutMs) - async def CallAsync(self, callFunct, timeoutMs: int = None): + async def CallAsyncWithResult(self, callFunct, timeoutMs: int = None): '''Run a Python function on CHIP stack, and wait for the response. This function will post a task on CHIP mainloop and waits for the call response in a asyncio friendly manner. ''' @@ -232,6 +232,11 @@ async def CallAsync(self, callFunct, timeoutMs: int = None): return await asyncio.wait_for(callObj.future, timeoutMs / 1000 if timeoutMs else None) + async def CallAsync(self, callFunct, timeoutMs: int = None) -> None: + '''Run a Python function on CHIP stack, and wait for the response.''' + res: PyChipError = await self.CallAsyncWithResult(callFunct, timeoutMs) + res.raise_on_error() + def PostTaskOnChipThread(self, callFunct) -> AsyncCallableHandle: '''Run a Python function on CHIP stack, and wait for the response. This function will post a task on CHIP mainloop, and return an object with Wait() method for getting the result. diff --git a/src/controller/python/chip/FabricAdmin.py b/src/controller/python/chip/FabricAdmin.py index fc20327e628bcc..d9e2e35cb2bcc4 100644 --- a/src/controller/python/chip/FabricAdmin.py +++ b/src/controller/python/chip/FabricAdmin.py @@ -25,6 +25,8 @@ from chip.crypto import p256keypair from chip.native import GetLibraryHandle +LOGGER = logging.getLogger(__name__) + class FabricAdmin: ''' Administers a fabric associated with a unique FabricID under a given CertificateAuthority @@ -34,10 +36,6 @@ class FabricAdmin: def _Handle(cls): return GetLibraryHandle() - @classmethod - def logger(cls): - return logging.getLogger('FabricAdmin') - def __init__(self, certificateAuthority: CertificateAuthority.CertificateAuthority, vendorId: int, fabricId: int = 1): ''' Initializes the object. @@ -60,7 +58,7 @@ def __init__(self, certificateAuthority: CertificateAuthority.CertificateAuthori self._fabricId = fabricId self._certificateAuthority = certificateAuthority - self.logger().warning(f"New FabricAdmin: FabricId: 0x{self._fabricId:016X}, VendorId = 0x{self.vendorId:04X}") + LOGGER.info(f"New FabricAdmin: FabricId: 0x{self._fabricId:016X}, VendorId = 0x{self.vendorId:04X}") self._isActive = True self._activeControllers = [] @@ -94,7 +92,7 @@ def NewController(self, nodeId: int = None, paaTrustStorePath: str = "", if (nodeId in nodeIdList): raise RuntimeError(f"Provided NodeId {nodeId} collides with an existing controller instance!") - self.logger().warning( + LOGGER.info( f"Allocating new controller with CaIndex: {self._certificateAuthority.caIndex}, " f"FabricId: 0x{self._fabricId:016X}, NodeId: 0x{nodeId:016X}, CatTags: {catTags}") diff --git a/src/controller/python/chip/clusters/Attribute.py b/src/controller/python/chip/clusters/Attribute.py index 36f5a794f9e73e..a8850f6b056186 100644 --- a/src/controller/python/chip/clusters/Attribute.py +++ b/src/controller/python/chip/clusters/Attribute.py @@ -40,6 +40,8 @@ from .ClusterObjects import Cluster, ClusterAttributeDescriptor, ClusterEvent +LOGGER = logging.getLogger(__name__) + @unique class EventTimestampType(Enum): @@ -467,7 +469,7 @@ def OverrideLivenessTimeoutMs(self, timeoutMs: int): async def TriggerResubscribeIfScheduled(self, reason: str): handle = chip.native.GetLibraryHandle() - await builtins.chipStack.CallAsync( + await builtins.chipStack.CallAsyncWithResult( lambda: handle.pychip_ReadClient_TriggerResubscribeIfScheduled( self._readTransaction._pReadClient, reason.encode("utf-8")) ) @@ -569,7 +571,7 @@ def subscriptionId(self) -> int: def Shutdown(self): if (self._isDone): - print("Subscription was already terminated previously!") + LOGGER.warning("Subscription 0x%08x was already terminated previously!", self.subscriptionId) return handle = chip.native.GetLibraryHandle() @@ -675,7 +677,7 @@ def handleAttributeData(self, path: AttributePath, dataVersion: int, status: int self._changedPathSet.add(path) except Exception as ex: - logging.exception(ex) + LOGGER.exception(ex) def handleEventData(self, header: EventHeader, path: EventPath, data: bytes, status: int): try: @@ -693,12 +695,12 @@ def handleEventData(self, header: EventHeader, path: EventPath, data: bytes, sta try: eventValue = eventType.FromTLV(data) except Exception as ex: - logging.error( + LOGGER.error( f"Error convering TLV to Cluster Object for path: Endpoint = {path.EndpointId}/" f"Cluster = {path.ClusterId}/Event = {path.EventId}") - logging.error( + LOGGER.error( f"Failed Cluster Object: {str(eventType)}") - logging.error(ex) + LOGGER.error(ex) eventValue = ValueDecodeFailure( tlvData, ex) @@ -715,9 +717,11 @@ def handleEventData(self, header: EventHeader, path: EventPath, data: bytes, sta eventResult, self._subscription_handler) except Exception as ex: - logging.exception(ex) + LOGGER.exception(ex) def handleError(self, chipError: PyChipError): + if self._subscription_handler: + self._subscription_handler.OnErrorCb(chipError.code, self._subscription_handler) self._resultError = chipError def _handleSubscriptionEstablished(self, subscriptionId): @@ -726,7 +730,7 @@ def _handleSubscriptionEstablished(self, subscriptionId): self, subscriptionId, self._devCtrl) self._future.set_result(self._subscription_handler) else: - logging.info("Re-subscription succeeded!") + self._subscription_handler._subscriptionId = subscriptionId if self._subscription_handler._onResubscriptionSucceededCb is not None: if (self._subscription_handler._onResubscriptionSucceededCb_isAsync): self._event_loop.create_task( @@ -761,7 +765,7 @@ def _handleReportEnd(self): attribute_path = TypedAttributePath(Path=change) except (KeyError, ValueError) as err: # path could not be resolved into a TypedAttributePath - logging.getLogger(__name__).exception(err) + LOGGER.exception(err) continue self._subscription_handler.OnAttributeChangeCb( attribute_path, self._subscription_handler) @@ -778,10 +782,7 @@ def _handleDone(self): # if not self._future.done(): if self._resultError is not None: - if self._subscription_handler: - self._subscription_handler.OnErrorCb(self._resultError.code, self._subscription_handler) - else: - self._future.set_exception(self._resultError.to_exception()) + self._future.set_exception(self._resultError.to_exception()) else: self._future.set_result(AsyncReadTransaction.ReadResponse( attributes=self._cache.attributeCache, events=self._events, tlvAttributes=self._cache.attributeTLVCache)) @@ -816,7 +817,7 @@ def handleResponse(self, path: AttributePath, status: int): imStatus = chip.interaction_model.Status(status) self._resultData.append(AttributeWriteResult(Path=path, Status=imStatus)) except ValueError as ex: - logging.exception(ex) + LOGGER.exception(ex) def handleError(self, chipError: PyChipError): self._resultError = chipError diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index db05bf7319200b..1901351596228a 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, @@ -7379,6 +7477,83 @@ class ChipClusters: }, }, } + _WATER_HEATER_MODE_CLUSTER_INFO = { + "clusterName": "WaterHeaterMode", + "clusterId": 0x0000009E, + "commands": { + 0x00000000: { + "commandId": 0x00000000, + "commandName": "ChangeToMode", + "args": { + "newMode": "int", + }, + }, + }, + "attributes": { + 0x00000000: { + "attributeName": "SupportedModes", + "attributeId": 0x00000000, + "type": "", + "reportable": True, + }, + 0x00000001: { + "attributeName": "CurrentMode", + "attributeId": 0x00000001, + "type": "int", + "reportable": True, + }, + 0x00000002: { + "attributeName": "StartUpMode", + "attributeId": 0x00000002, + "type": "int", + "reportable": True, + "writable": True, + }, + 0x00000003: { + "attributeName": "OnMode", + "attributeId": 0x00000003, + "type": "int", + "reportable": True, + "writable": 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, + }, + }, + } _DEVICE_ENERGY_MANAGEMENT_MODE_CLUSTER_INFO = { "clusterName": "DeviceEnergyManagementMode", "clusterId": 0x0000009F, @@ -11714,16 +11889,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 +11930,9 @@ class ChipClusters: "type": "bool", "reportable": True, }, - 0x00000005: { + 0x00000004: { "attributeName": "ActiveDatasetTimestamp", - "attributeId": 0x00000005, + "attributeId": 0x00000004, "type": "int", "reportable": True, }, @@ -13101,6 +13276,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 +15205,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, @@ -14967,6 +15213,7 @@ class ChipClusters: 0x0000009B: _ENERGY_PREFERENCE_CLUSTER_INFO, 0x0000009C: _POWER_TOPOLOGY_CLUSTER_INFO, 0x0000009D: _ENERGY_EVSE_MODE_CLUSTER_INFO, + 0x0000009E: _WATER_HEATER_MODE_CLUSTER_INFO, 0x0000009F: _DEVICE_ENERGY_MANAGEMENT_MODE_CLUSTER_INFO, 0x00000101: _DOOR_LOCK_CLUSTER_INFO, 0x00000102: _WINDOW_COVERING_CLUSTER_INFO, @@ -15011,6 +15258,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 +15333,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, @@ -15092,6 +15341,7 @@ class ChipClusters: "EnergyPreference": _ENERGY_PREFERENCE_CLUSTER_INFO, "PowerTopology": _POWER_TOPOLOGY_CLUSTER_INFO, "EnergyEvseMode": _ENERGY_EVSE_MODE_CLUSTER_INFO, + "WaterHeaterMode": _WATER_HEATER_MODE_CLUSTER_INFO, "DeviceEnergyManagementMode": _DEVICE_ENERGY_MANAGEMENT_MODE_CLUSTER_INFO, "DoorLock": _DOOR_LOCK_CLUSTER_INFO, "WindowCovering": _WINDOW_COVERING_CLUSTER_INFO, @@ -15136,6 +15386,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/Command.py b/src/controller/python/chip/clusters/Command.py index 93951338f988f5..785bb3d3daf47f 100644 --- a/src/controller/python/chip/clusters/Command.py +++ b/src/controller/python/chip/clusters/Command.py @@ -316,7 +316,7 @@ async def SendCommand(future: Future, eventLoop, responseType: Type, device, com payloadTLV = payload.ToTLV() ctypes.pythonapi.Py_IncRef(ctypes.py_object(transaction)) - return await builtins.chipStack.CallAsync( + return await builtins.chipStack.CallAsyncWithResult( lambda: handle.pychip_CommandSender_SendCommand( ctypes.py_object(transaction), device, c_uint16(0 if timedRequestTimeoutMs is None else timedRequestTimeoutMs), commandPath.EndpointId, @@ -388,7 +388,7 @@ async def SendBatchCommands(future: Future, eventLoop, device, commands: List[In transaction = AsyncBatchCommandsTransaction(future, eventLoop, responseTypes) ctypes.pythonapi.Py_IncRef(ctypes.py_object(transaction)) - return await builtins.chipStack.CallAsync( + return await builtins.chipStack.CallAsyncWithResult( lambda: handle.pychip_CommandSender_SendBatchCommands( py_object(transaction), device, c_uint16(0 if timedRequestTimeoutMs is None else timedRequestTimeoutMs), diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 516e2f5a2e7800..7b0c4a0cd6bc37 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): @@ -26118,23 +26421,295 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: class ActiveEndpoints(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009C + return 0x0000009C + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000001 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[uint]]) + + value: 'typing.Optional[typing.List[uint]]' = None + + @dataclass + class GeneratedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009C + + @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 0x0000009C + + @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 0x0000009C + + @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 0x0000009C + + @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 0x0000009C + + @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 0x0000009C + + @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 EnergyEvseMode(Cluster): + id: typing.ClassVar[int] = 0x0000009D + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="supportedModes", Tag=0x00000000, Type=typing.List[EnergyEvseMode.Structs.ModeOptionStruct]), + ClusterObjectFieldDescriptor(Label="currentMode", Tag=0x00000001, Type=uint), + ClusterObjectFieldDescriptor(Label="startUpMode", Tag=0x00000002, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="onMode", Tag=0x00000003, Type=typing.Union[None, 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]), + ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), + ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), + ]) + + supportedModes: 'typing.List[EnergyEvseMode.Structs.ModeOptionStruct]' = None + currentMode: 'uint' = None + startUpMode: 'typing.Union[None, Nullable, uint]' = None + onMode: 'typing.Union[None, Nullable, 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 Enums: + class ModeTag(MatterIntEnum): + kManual = 0x4000 + kTimeOfUse = 0x4001 + kSolarCharging = 0x4002 + # kUnknownEnumValue intentionally not defined. This enum never goes + # through DataModel::Decode, likely because it is a part of a derived + # cluster. As a result having kUnknownEnumValue in this enum is error + # prone, and was removed. See + # src/app/common/templates/config-data.yaml. + + class Bitmaps: + class Feature(IntFlag): + kOnOff = 0x1 + + class Structs: + @dataclass + class ModeTagStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="mfgCode", Tag=0, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="value", Tag=1, Type=uint), + ]) + + mfgCode: 'typing.Optional[uint]' = None + value: 'uint' = 0 + + @dataclass + class ModeOptionStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="label", Tag=0, Type=str), + ClusterObjectFieldDescriptor(Label="mode", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="modeTags", Tag=2, Type=typing.List[EnergyEvseMode.Structs.ModeTagStruct]), + ]) + + label: 'str' = "" + mode: 'uint' = 0 + modeTags: 'typing.List[EnergyEvseMode.Structs.ModeTagStruct]' = field(default_factory=lambda: []) + + class Commands: + @dataclass + class ChangeToMode(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x0000009D + command_id: typing.ClassVar[int] = 0x00000000 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'ChangeToModeResponse' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="newMode", Tag=0, Type=uint), + ]) + + newMode: 'uint' = 0 + + @dataclass + class ChangeToModeResponse(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x0000009D + command_id: typing.ClassVar[int] = 0x00000001 + is_client: typing.ClassVar[bool] = False + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="status", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=typing.Optional[str]), + ]) + + status: 'uint' = 0 + statusText: 'typing.Optional[str]' = None + + class Attributes: + @dataclass + class SupportedModes(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009D + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[EnergyEvseMode.Structs.ModeOptionStruct]) + + value: 'typing.List[EnergyEvseMode.Structs.ModeOptionStruct]' = field(default_factory=lambda: []) + + @dataclass + class CurrentMode(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009D + + @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 StartUpMode(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009D + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000002 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) + + value: 'typing.Union[None, Nullable, uint]' = None + + @dataclass + class OnMode(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009D @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000001 + return 0x00000003 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[uint]]) + return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Optional[typing.List[uint]]' = None + value: 'typing.Union[None, Nullable, uint]' = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009C + return 0x0000009D @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -26150,7 +26725,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: class AcceptedCommandList(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009C + return 0x0000009D @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -26166,7 +26741,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: class EventList(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009C + return 0x0000009D @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -26182,7 +26757,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009C + return 0x0000009D @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -26198,7 +26773,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: class FeatureMap(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009C + return 0x0000009D @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -26214,7 +26789,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: class ClusterRevision(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009C + return 0x0000009D @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -26228,14 +26803,14 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: @dataclass -class EnergyEvseMode(Cluster): - id: typing.ClassVar[int] = 0x0000009D +class WaterHeaterMode(Cluster): + id: typing.ClassVar[int] = 0x0000009E @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="supportedModes", Tag=0x00000000, Type=typing.List[EnergyEvseMode.Structs.ModeOptionStruct]), + ClusterObjectFieldDescriptor(Label="supportedModes", Tag=0x00000000, Type=typing.List[WaterHeaterMode.Structs.ModeOptionStruct]), ClusterObjectFieldDescriptor(Label="currentMode", Tag=0x00000001, Type=uint), ClusterObjectFieldDescriptor(Label="startUpMode", Tag=0x00000002, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="onMode", Tag=0x00000003, Type=typing.Union[None, Nullable, uint]), @@ -26247,7 +26822,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedModes: 'typing.List[EnergyEvseMode.Structs.ModeOptionStruct]' = None + supportedModes: 'typing.List[WaterHeaterMode.Structs.ModeOptionStruct]' = None currentMode: 'uint' = None startUpMode: 'typing.Union[None, Nullable, uint]' = None onMode: 'typing.Union[None, Nullable, uint]' = None @@ -26260,14 +26835,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: class Enums: class ModeTag(MatterIntEnum): - kManual = 0x4000 - kTimeOfUse = 0x4001 - kSolarCharging = 0x4002 - # kUnknownEnumValue intentionally not defined. This enum never goes - # through DataModel::Decode, likely because it is a part of a derived - # cluster. As a result having kUnknownEnumValue in this enum is error - # prone, and was removed. See - # src/app/common/templates/config-data.yaml. + kOff = 0x4000 + kManual = 0x4001 + kTimed = 0x4002 + # 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 = 0, class Bitmaps: class Feature(IntFlag): @@ -26295,17 +26870,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="label", Tag=0, Type=str), ClusterObjectFieldDescriptor(Label="mode", Tag=1, Type=uint), - ClusterObjectFieldDescriptor(Label="modeTags", Tag=2, Type=typing.List[EnergyEvseMode.Structs.ModeTagStruct]), + ClusterObjectFieldDescriptor(Label="modeTags", Tag=2, Type=typing.List[WaterHeaterMode.Structs.ModeTagStruct]), ]) label: 'str' = "" mode: 'uint' = 0 - modeTags: 'typing.List[EnergyEvseMode.Structs.ModeTagStruct]' = field(default_factory=lambda: []) + modeTags: 'typing.List[WaterHeaterMode.Structs.ModeTagStruct]' = field(default_factory=lambda: []) class Commands: @dataclass class ChangeToMode(ClusterCommand): - cluster_id: typing.ClassVar[int] = 0x0000009D + cluster_id: typing.ClassVar[int] = 0x0000009E command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True response_type: typing.ClassVar[str] = 'ChangeToModeResponse' @@ -26321,7 +26896,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: @dataclass class ChangeToModeResponse(ClusterCommand): - cluster_id: typing.ClassVar[int] = 0x0000009D + cluster_id: typing.ClassVar[int] = 0x0000009E command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False response_type: typing.ClassVar[str] = None @@ -26342,7 +26917,7 @@ class Attributes: class SupportedModes(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009D + return 0x0000009E @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -26350,15 +26925,15 @@ def attribute_id(cls) -> int: @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[EnergyEvseMode.Structs.ModeOptionStruct]) + return ClusterObjectFieldDescriptor(Type=typing.List[WaterHeaterMode.Structs.ModeOptionStruct]) - value: 'typing.List[EnergyEvseMode.Structs.ModeOptionStruct]' = field(default_factory=lambda: []) + value: 'typing.List[WaterHeaterMode.Structs.ModeOptionStruct]' = field(default_factory=lambda: []) @dataclass class CurrentMode(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009D + return 0x0000009E @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -26374,7 +26949,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: class StartUpMode(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009D + return 0x0000009E @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -26390,7 +26965,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: class OnMode(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009D + return 0x0000009E @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -26406,7 +26981,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: class GeneratedCommandList(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009D + return 0x0000009E @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -26422,7 +26997,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: class AcceptedCommandList(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009D + return 0x0000009E @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -26438,7 +27013,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: class EventList(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009D + return 0x0000009E @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -26454,7 +27029,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009D + return 0x0000009E @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -26470,7 +27045,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: class FeatureMap(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009D + return 0x0000009E @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -26486,7 +27061,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: class ClusterRevision(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: - return 0x0000009D + return 0x0000009E @ChipUtility.classproperty def attribute_id(cls) -> int: @@ -41148,7 +41723,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 +41778,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 +41794,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 +41812,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 +41898,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 +46642,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/clusters/__init__.py b/src/controller/python/chip/clusters/__init__.py index 473e3f70a4f8d9..1aa2a61a8911d6 100644 --- a/src/controller/python/chip/clusters/__init__.py +++ b/src/controller/python/chip/clusters/__init__.py @@ -46,7 +46,8 @@ TemperatureControl, TemperatureMeasurement, Thermostat, ThermostatUserInterfaceConfiguration, ThreadBorderRouterManagement, ThreadNetworkDiagnostics, TimeFormatLocalization, TimeSynchronization, TotalVolatileOrganicCompoundsConcentrationMeasurement, UnitLocalization, UnitTesting, UserLabel, - ValveConfigurationAndControl, WakeOnLan, WiFiNetworkDiagnostics, WindowCovering) + ValveConfigurationAndControl, WakeOnLan, WaterHeaterManagement, WaterHeaterMode, WiFiNetworkDiagnostics, + WindowCovering) __all__ = [Attribute, CHIPClusters, Command, AccessControl, AccountLogin, Actions, ActivatedCarbonFilterMonitoring, AdministratorCommissioning, AirQuality, ApplicationBasic, ApplicationLauncher, AudioOutput, BallastConfiguration, BarrierControl, BasicInformation, @@ -69,4 +70,4 @@ Switch, TargetNavigator, TemperatureControl, TemperatureMeasurement, Thermostat, ThermostatUserInterfaceConfiguration, ThreadBorderRouterManagement, ThreadNetworkDiagnostics, TimeFormatLocalization, TimeSynchronization, TotalVolatileOrganicCompoundsConcentrationMeasurement, UnitLocalization, - UnitTesting, UserLabel, ValveConfigurationAndControl, WakeOnLan, WiFiNetworkDiagnostics, WindowCovering] + UnitTesting, UserLabel, ValveConfigurationAndControl, WakeOnLan, WaterHeaterManagement, WaterHeaterMode, WiFiNetworkDiagnostics, WindowCovering] diff --git a/src/controller/python/chip/clusters/attribute.cpp b/src/controller/python/chip/clusters/attribute.cpp index 7c5b2c906ab69c..421284a0ae795b 100644 --- a/src/controller/python/chip/clusters/attribute.cpp +++ b/src/controller/python/chip/clusters/attribute.cpp @@ -145,18 +145,20 @@ class ReadClientCallback : public ReadClient::Callback void OnSubscriptionEstablished(SubscriptionId aSubscriptionId) override { + // Only enable auto resubscribe if the subscription is established successfully. + mAutoResubscribeNeeded = mAutoResubscribe; gOnSubscriptionEstablishedCallback(mAppContext, aSubscriptionId); } CHIP_ERROR OnResubscriptionNeeded(ReadClient * apReadClient, CHIP_ERROR aTerminationCause) override { - if (mAutoResubscribe) + if (mAutoResubscribeNeeded) { ReturnErrorOnFailure(ReadClient::Callback::OnResubscriptionNeeded(apReadClient, aTerminationCause)); } gOnResubscriptionAttemptedCallback(mAppContext, ToPyChipError(aTerminationCause), apReadClient->ComputeTimeTillNextSubscription()); - if (mAutoResubscribe) + if (mAutoResubscribeNeeded) { return CHIP_NO_ERROR; } @@ -242,7 +244,8 @@ class ReadClientCallback : public ReadClient::Callback PyObject * mAppContext; std::unique_ptr mReadClient; - bool mAutoResubscribe = true; + bool mAutoResubscribe = true; + bool mAutoResubscribeNeeded = false; }; extern "C" { diff --git a/src/controller/python/chip/clusters/command.cpp b/src/controller/python/chip/clusters/command.cpp index d65766b7989d4d..037c848f96fae0 100644 --- a/src/controller/python/chip/clusters/command.cpp +++ b/src/controller/python/chip/clusters/command.cpp @@ -203,10 +203,13 @@ PyChipError SendBatchCommandsInternal(void * appContext, DeviceProxy * device, u CHIP_ERROR err = CHIP_NO_ERROR; bool testOnlySuppressTimedRequestMessage = false; - uint16_t * testOnlyCommandRefsOverride = nullptr; +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST + uint16_t * testOnlyCommandRefsOverride = nullptr; +#endif VerifyOrReturnError(device->GetSecureSession().HasValue(), ToPyChipError(CHIP_ERROR_MISSING_SECURE_SESSION)); +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST // Test only override validation checks and setup if (testOnlyOverrides != nullptr) { @@ -228,6 +231,7 @@ PyChipError SendBatchCommandsInternal(void * appContext, DeviceProxy * device, u config.SetRemoteMaxPathsPerInvoke(testOnlyOverrides->overrideRemoteMaxPathsPerInvoke); } else +#endif { auto remoteSessionParameters = device->GetSecureSession().Value()->GetRemoteSessionParameters(); config.SetRemoteMaxPathsPerInvoke(remoteSessionParameters.GetMaxPathsPerInvoke()); @@ -273,6 +277,7 @@ PyChipError SendBatchCommandsInternal(void * appContext, DeviceProxy * device, u Optional timedRequestTimeout = timedRequestTimeoutMs != 0 ? Optional(timedRequestTimeoutMs) : Optional::Missing(); CommandSender::FinishCommandParameters finishCommandParams(timedRequestTimeout); +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST if (testOnlyCommandRefsOverride != nullptr) { finishCommandParams.commandRef.SetValue(testOnlyCommandRefsOverride[i]); @@ -291,6 +296,7 @@ PyChipError SendBatchCommandsInternal(void * appContext, DeviceProxy * device, u callback->AddCommandRefToIndexLookup(finishCommandParams.commandRef.Value(), i); } else +#endif { SuccessOrExit(err = callback->AddCommandRefToIndexLookup(finishCommandParams.commandRef.Value(), i)); } @@ -300,12 +306,14 @@ PyChipError SendBatchCommandsInternal(void * appContext, DeviceProxy * device, u Optional interactionTimeout = interactionTimeoutMs != 0 ? MakeOptional(System::Clock::Milliseconds32(interactionTimeoutMs)) : Optional::Missing(); +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST if (testOnlySuppressTimedRequestMessage) { SuccessOrExit(err = sender->TestOnlyCommandSenderTimedRequestFlagWithNoTimedInvoke(device->GetSecureSession().Value(), interactionTimeout)); } else +#endif { SuccessOrExit(err = sender->SendCommandRequest(device->GetSecureSession().Value(), interactionTimeout)); } 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/storage/__init__.py b/src/controller/python/chip/storage/__init__.py index 385efca6be1c8c..20432dcd01870b 100644 --- a/src/controller/python/chip/storage/__init__.py +++ b/src/controller/python/chip/storage/__init__.py @@ -29,6 +29,8 @@ import chip.exceptions import chip.native +LOGGER = logging.getLogger(__name__) + _SyncSetKeyValueCbFunct = CFUNCTYPE( None, py_object, c_char_p, POINTER(c_char), c_uint16) _SyncGetKeyValueCbFunct = CFUNCTYPE( @@ -91,9 +93,6 @@ class PersistentStorage: Object must be resident before the Matter stack starts up and last past its shutdown. ''' - @classmethod - def logger(cls): - return logging.getLogger('PersistentStorage') def __init__(self, path: str = None, jsonData: Dict = None): ''' Initializes the object with either a path to a JSON file that contains the configuration OR @@ -109,9 +108,9 @@ def __init__(self, path: str = None, jsonData: Dict = None): raise ValueError("Can't provide both a valid path and jsonData") if (path is not None): - self.logger().warn(f"Initializing persistent storage from file: {path}") + LOGGER.info(f"Initializing persistent storage from file: {path}") else: - self.logger().warn("Initializing persistent storage from dict") + LOGGER.info("Initializing persistent storage from dict") self._handle = chip.native.GetLibraryHandle() self._isActive = True @@ -125,24 +124,24 @@ def __init__(self, path: str = None, jsonData: Dict = None): self._file.seek(0) if (size != 0): - self.logger().warn(f"Loading configuration from {path}...") + LOGGER.info(f"Loading configuration from {path}...") self._jsonData = json.load(self._file) else: self._jsonData = {} except Exception as ex: - logging.error(ex) - logging.critical(f"Could not load configuration from {path} - resetting configuration...") + LOGGER.error(ex) + LOGGER.critical(f"Could not load configuration from {path} - resetting configuration...") self._jsonData = {} else: self._jsonData = jsonData if ('sdk-config' not in self._jsonData): - logging.warn("No valid SDK configuration present - clearing out configuration") + LOGGER.warn("No valid SDK configuration present - clearing out configuration") self._jsonData['sdk-config'] = {} if ('repl-config' not in self._jsonData): - logging.warn("No valid REPL configuration present - clearing out configuration") + LOGGER.warn("No valid REPL configuration present - clearing out configuration") self._jsonData['repl-config'] = {} # Clear out the file so that calling 'Commit' will re-open the file at that time in write mode. @@ -166,7 +165,6 @@ def Commit(self): ''' Commits the cached JSON configuration to file (if one was provided in the constructor). Otherwise, this is a no-op. ''' - self.logger().info("Committing...") if (self._path is None): return @@ -175,9 +173,8 @@ def Commit(self): try: self._file = open(self._path, 'w') except Exception as ex: - logging.warn( - f"Could not open {self._path} for writing configuration. Error:") - logging.warn(ex) + LOGGER.error( + f"Could not open {self._path} for writing configuration. Error: {ex}") return self._file.seek(0) @@ -188,7 +185,7 @@ def Commit(self): def SetReplKey(self, key: str, value): ''' Set a REPL key to a specific value. Creates the key if one doesn't exist already. ''' - self.logger().info(f"SetReplKey: {key} = {value}") + LOGGER.debug(f"SetReplKey: {key} = {value}") if (key is None or key == ''): raise ValueError("Invalid Key") @@ -212,7 +209,7 @@ def GetReplKey(self, key: str): def SetSdkKey(self, key: str, value: bytes): ''' Set an SDK key to a specific value. Creates the key if one doesn't exist already. ''' - self.logger().info(f"SetSdkKey: {key} = {value}") + LOGGER.debug(f"SetSdkKey: {key} = {value}") if (key is None or key == ''): raise ValueError("Invalid Key") @@ -236,7 +233,7 @@ def GetSdkKey(self, key: str): def DeleteSdkKey(self, key: str): ''' Deletes an SDK key if one exists. ''' - self.logger().info(f"DeleteSdkKey: {key}") + LOGGER.debug(f"DeleteSdkKey: {key}") del (self._jsonData['sdk-config'][key]) self.Commit() 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..79ad383ef3f2f0 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,18 @@ # Commissioning test. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# 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 +# === END CI TEST ARGUMENTS === + import asyncio import os diff --git a/src/controller/tests/BUILD.gn b/src/controller/tests/BUILD.gn index 1e2b15d7778beb..7b3dff0e27d441 100644 --- a/src/controller/tests/BUILD.gn +++ b/src/controller/tests/BUILD.gn @@ -39,6 +39,7 @@ chip_test_suite("tests") { "${chip_root}/src/app/common:cluster-objects", "${chip_root}/src/app/tests:helpers", "${chip_root}/src/controller", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/messaging/tests:helpers", "${chip_root}/src/transport/raw/tests:helpers", diff --git a/src/controller/tests/TestCommissionableNodeController.cpp b/src/controller/tests/TestCommissionableNodeController.cpp index 6d9ef65db11e97..e113bc38add8f1 100644 --- a/src/controller/tests/TestCommissionableNodeController.cpp +++ b/src/controller/tests/TestCommissionableNodeController.cpp @@ -16,9 +16,10 @@ * limitations under the License. */ -#include +#include #include +#include #include using namespace chip; diff --git a/src/controller/tests/TestEventCaching.cpp b/src/controller/tests/TestEventCaching.cpp index b4c262725f74d3..cbff4b743ea0dd 100644 --- a/src/controller/tests/TestEventCaching.cpp +++ b/src/controller/tests/TestEventCaching.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" @@ -34,10 +34,10 @@ #include #include #include +#include #include #include #include -#include using namespace chip; using namespace chip::app; @@ -50,8 +50,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 +57,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 +69,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 +149,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 +177,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 +310,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 +362,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 +375,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 +411,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 +444,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..0aa0b9d0a5714f 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" @@ -38,10 +38,10 @@ #include #include #include +#include #include #include #include -#include using namespace chip; using namespace chip::app; @@ -54,8 +54,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 +67,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 +79,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 +93,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 +289,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 +330,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 +355,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 +398,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 +412,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 +431,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 +474,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..9b580f759e06c1 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" @@ -31,9 +31,9 @@ #include #include #include +#include #include #include -#include using namespace chip; using namespace chip::app; @@ -46,8 +46,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 +53,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 +65,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 +79,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 +140,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 +171,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 +195,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 +214,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 +228,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..b00d0bed75ebcf 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" @@ -41,12 +41,11 @@ #include #include #include +#include #include #include #include -#include -using TestContext = chip::Test::AppContext; using namespace chip; using namespace chip::app; using namespace chip::app::Clusters; @@ -72,42 +71,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 +455,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 +483,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 +514,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 +528,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 +545,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 +589,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 +626,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 +646,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 +667,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 +683,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 +697,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 +717,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 +746,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 +756,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 +769,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 +817,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 +878,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 +925,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 +937,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 +949,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 +963,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 +974,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 +1004,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 +1023,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..8c895008dfd67e 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" @@ -35,10 +35,8 @@ #include #include #include +#include #include -#include - -using TestContext = chip::Test::AppContext; using namespace chip; using namespace chip::app; @@ -130,45 +128,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 +145,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 +167,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 +225,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 +271,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 +310,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..9ffad2c602835c 100644 --- a/src/controller/tests/TestWriteChunking.cpp +++ b/src/controller/tests/TestWriteChunking.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include "app-common/zap-generated/ids/Attributes.h" #include "app-common/zap-generated/ids/Clusters.h" @@ -37,10 +37,9 @@ #include #include #include +#include #include -#include -using TestContext = chip::Test::AppContext; using namespace chip; using namespace chip::app; using namespace chip::app::Clusters; @@ -62,41 +61,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 +208,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 +235,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 +253,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 +278,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 +303,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 +332,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 +349,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 +360,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 +377,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 +399,7 @@ TEST_F(TestWriteChunking, TestConflictWrite) err = writeClient2.SendWriteRequest(sessionHandle); EXPECT_EQ(err, CHIP_NO_ERROR); - mpContext->DrainAndServiceIO(); + DrainAndServiceIO(); { const TestWriteCallback * writeCallbackRef1 = &writeCallback1; @@ -426,7 +423,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 +434,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 +452,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 +474,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 +486,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 +566,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 +582,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 +595,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/DataModelFixtures.cpp b/src/controller/tests/data_model/DataModelFixtures.cpp index 11dbd1059f7415..2e5d7e65f7ee42 100644 --- a/src/controller/tests/data_model/DataModelFixtures.cpp +++ b/src/controller/tests/data_model/DataModelFixtures.cpp @@ -312,15 +312,15 @@ CHIP_ERROR WriteSingleClusterData(const Access::SubjectDescriptor & aSubjectDesc // Boolean attribute of unit testing cluster triggers "multiple errors" case. if (aPath.mClusterId == Clusters::UnitTesting::Id && aPath.mAttributeId == Attributes::Boolean::TypeInfo::GetAttributeId()) { - InteractionModel::ClusterStatusCode status{ Protocols::InteractionModel::Status::InvalidValue }; + Protocols::InteractionModel::ClusterStatusCode status{ Protocols::InteractionModel::Status::InvalidValue }; if (gWriteResponseDirective == WriteResponseDirective::kSendMultipleSuccess) { - status = InteractionModel::Status::Success; + status = Protocols::InteractionModel::Status::Success; } else if (gWriteResponseDirective == WriteResponseDirective::kSendMultipleErrors) { - status = InteractionModel::Status::Failure; + status = Protocols::InteractionModel::Status::Failure; } else { @@ -337,14 +337,14 @@ CHIP_ERROR WriteSingleClusterData(const Access::SubjectDescriptor & aSubjectDesc if (aPath.mClusterId == Clusters::UnitTesting::Id && aPath.mAttributeId == Attributes::Int8u::TypeInfo::GetAttributeId()) { - InteractionModel::ClusterStatusCode status{ Protocols::InteractionModel::Status::InvalidValue }; + Protocols::InteractionModel::ClusterStatusCode status{ Protocols::InteractionModel::Status::InvalidValue }; if (gWriteResponseDirective == WriteResponseDirective::kSendClusterSpecificSuccess) { - status = InteractionModel::ClusterStatusCode::ClusterSpecificSuccess(kExampleClusterSpecificSuccess); + status = Protocols::InteractionModel::ClusterStatusCode::ClusterSpecificSuccess(kExampleClusterSpecificSuccess); } else if (gWriteResponseDirective == WriteResponseDirective::kSendClusterSpecificFailure) { - status = InteractionModel::ClusterStatusCode::ClusterSpecificFailure(kExampleClusterSpecificFailure); + status = Protocols::InteractionModel::ClusterStatusCode::ClusterSpecificFailure(kExampleClusterSpecificFailure); } else { @@ -446,10 +446,10 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip } } -InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) +Protocols::InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) { // Mock cluster catalog, only support commands on one cluster on one endpoint. - using InteractionModel::Status; + using Protocols::InteractionModel::Status; if (aCommandPath.mEndpointId != kTestEndpointId) { diff --git a/src/controller/tests/data_model/TestCommands.cpp b/src/controller/tests/data_model/TestCommands.cpp index 2ccb98d5cf7e00..4e8b3dd39adb74 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; @@ -194,7 +165,7 @@ TEST_F(TestCommands, TestMultipleSuccessNoDataResponses) // not safe to do so. auto onSuccessCb = [&successCalls, &statusCheck](const ConcreteCommandPath & commandPath, const StatusIB & aStatus, const auto & dataResponse) { - statusCheck = (aStatus.mStatus == InteractionModel::Status::Success); + statusCheck = (aStatus.mStatus == Protocols::InteractionModel::Status::Success); ++successCalls; }; @@ -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; @@ -320,20 +290,19 @@ TEST_F(TestCommands, TestMultipleFailures) // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's // not safe to do so. auto onFailureCb = [&failureCalls, &statusCheck](CHIP_ERROR aError) { - statusCheck = aError.IsIMStatus() && StatusIB(aError).mStatus == InteractionModel::Status::Failure; + statusCheck = aError.IsIMStatus() && StatusIB(aError).mStatus == Protocols::InteractionModel::Status::Failure; ++failureCalls; }; 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/credentials/tests/BUILD.gn b/src/credentials/tests/BUILD.gn index 2ec6db203bcaa0..99cb1e8e20d322 100644 --- a/src/credentials/tests/BUILD.gn +++ b/src/credentials/tests/BUILD.gn @@ -69,6 +69,7 @@ chip_test_suite("tests") { "${chip_root}/src/credentials", "${chip_root}/src/credentials:default_attestation_verifier", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support:testing", ] } diff --git a/src/credentials/tests/TestCertificationDeclaration.cpp b/src/credentials/tests/TestCertificationDeclaration.cpp index 45c8d5027bac93..ecc1372dd43bf9 100644 --- a/src/credentials/tests/TestCertificationDeclaration.cpp +++ b/src/credentials/tests/TestCertificationDeclaration.cpp @@ -25,14 +25,15 @@ #include #include +#include + #include #include #include #include +#include #include -#include - using namespace chip; using namespace chip::ASN1; using namespace chip::Crypto; diff --git a/src/credentials/tests/TestChipCert.cpp b/src/credentials/tests/TestChipCert.cpp index 9a6e50b58561fb..94d53c7ae1619e 100644 --- a/src/credentials/tests/TestChipCert.cpp +++ b/src/credentials/tests/TestChipCert.cpp @@ -24,18 +24,19 @@ * */ +#include + #include #include #include #include #include #include +#include #include #include #include -#include - #include "CHIPCert_error_test_vectors.h" #include "CHIPCert_test_vectors.h" diff --git a/src/credentials/tests/TestCommissionerDUTVectors.cpp b/src/credentials/tests/TestCommissionerDUTVectors.cpp index c512776cc89a69..a3c0ac7f85f885 100644 --- a/src/credentials/tests/TestCommissionerDUTVectors.cpp +++ b/src/credentials/tests/TestCommissionerDUTVectors.cpp @@ -15,6 +15,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include + #include #include @@ -27,11 +30,10 @@ #include #include +#include #include #include -#include - #include #include #include diff --git a/src/credentials/tests/TestDeviceAttestationConstruction.cpp b/src/credentials/tests/TestDeviceAttestationConstruction.cpp index e624b257a32ef2..8fc949ca29c999 100644 --- a/src/credentials/tests/TestDeviceAttestationConstruction.cpp +++ b/src/credentials/tests/TestDeviceAttestationConstruction.cpp @@ -15,17 +15,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include + +#include + #include #include #include +#include #include #include #include #include -#include -#include - using namespace chip; using namespace chip::Credentials; diff --git a/src/credentials/tests/TestDeviceAttestationCredentials.cpp b/src/credentials/tests/TestDeviceAttestationCredentials.cpp index bf203c8321adf1..85a5d4edfa58a2 100644 --- a/src/credentials/tests/TestDeviceAttestationCredentials.cpp +++ b/src/credentials/tests/TestDeviceAttestationCredentials.cpp @@ -15,6 +15,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include + #include #include @@ -28,11 +31,10 @@ #include #include +#include #include #include -#include - #include "CHIPAttCert_test_vectors.h" using namespace chip; diff --git a/src/credentials/tests/TestFabricTable.cpp b/src/credentials/tests/TestFabricTable.cpp index 75f51c1c2cb402..c5b78fc13e5b4f 100644 --- a/src/credentials/tests/TestFabricTable.cpp +++ b/src/credentials/tests/TestFabricTable.cpp @@ -22,9 +22,12 @@ */ #include -#include +#include + +#include #include +#include #include @@ -41,8 +44,6 @@ #include -#include - using namespace chip; using namespace chip::Credentials; diff --git a/src/credentials/tests/TestGroupDataProvider.cpp b/src/credentials/tests/TestGroupDataProvider.cpp index 7718cf0ee49cd2..6628b939012624 100644 --- a/src/credentials/tests/TestGroupDataProvider.cpp +++ b/src/credentials/tests/TestGroupDataProvider.cpp @@ -16,17 +16,20 @@ * limitations under the License. */ +#include +#include +#include +#include + +#include + #include #include -#include +#include #include #include #include #include -#include -#include -#include -#include using namespace chip::Credentials; using GroupInfo = GroupDataProvider::GroupInfo; diff --git a/src/credentials/tests/TestPersistentStorageOpCertStore.cpp b/src/credentials/tests/TestPersistentStorageOpCertStore.cpp index c1a57e00e95af2..d558818bb40f89 100644 --- a/src/credentials/tests/TestPersistentStorageOpCertStore.cpp +++ b/src/credentials/tests/TestPersistentStorageOpCertStore.cpp @@ -18,8 +18,10 @@ #include +#include + #include -#include +#include #include #include #include diff --git a/src/crypto/tests/BUILD.gn b/src/crypto/tests/BUILD.gn index 8570ed3defc157..d495f68ab54317 100644 --- a/src/crypto/tests/BUILD.gn +++ b/src/crypto/tests/BUILD.gn @@ -68,6 +68,7 @@ chip_test_suite("tests") { "${chip_root}/src/credentials/tests:cert_test_vectors", "${chip_root}/src/crypto", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support:testing", "${chip_root}/src/platform", ] diff --git a/src/crypto/tests/TestChipCryptoPAL.cpp b/src/crypto/tests/TestChipCryptoPAL.cpp index b4e0fbb2558057..2d1f5c0612217a 100644 --- a/src/crypto/tests/TestChipCryptoPAL.cpp +++ b/src/crypto/tests/TestChipCryptoPAL.cpp @@ -35,10 +35,12 @@ #include "SPAKE2P_POINT_VALID_test_vectors.h" #include "SPAKE2P_RFC_test_vectors.h" +#include + #include #include -#include #include +#include #include #include diff --git a/src/crypto/tests/TestGroupOperationalCredentials.cpp b/src/crypto/tests/TestGroupOperationalCredentials.cpp index 941423e327f873..9185704acd9d1c 100644 --- a/src/crypto/tests/TestGroupOperationalCredentials.cpp +++ b/src/crypto/tests/TestGroupOperationalCredentials.cpp @@ -18,12 +18,13 @@ #include +#include + #include #include +#include #include -#include - using namespace chip; using namespace chip::Crypto; diff --git a/src/crypto/tests/TestPSAOpKeyStore.cpp b/src/crypto/tests/TestPSAOpKeyStore.cpp index 4a16a19e254b60..ae3b142c27e25b 100644 --- a/src/crypto/tests/TestPSAOpKeyStore.cpp +++ b/src/crypto/tests/TestPSAOpKeyStore.cpp @@ -18,16 +18,17 @@ #include +#include + #include #include +#include #include #include #include #include #include -#include - using namespace chip; using namespace chip::Crypto; diff --git a/src/crypto/tests/TestPersistentStorageOpKeyStore.cpp b/src/crypto/tests/TestPersistentStorageOpKeyStore.cpp index 4448004ff2d3a3..26cf12ca7c2a1a 100644 --- a/src/crypto/tests/TestPersistentStorageOpKeyStore.cpp +++ b/src/crypto/tests/TestPersistentStorageOpKeyStore.cpp @@ -17,18 +17,18 @@ */ #include +#include + +#include #include +#include #include #include #include #include #include -#include - -#include - using namespace chip; using namespace chip::Crypto; diff --git a/src/crypto/tests/TestSessionKeystore.cpp b/src/crypto/tests/TestSessionKeystore.cpp index b3908d1695aaac..372ac0ad02c850 100644 --- a/src/crypto/tests/TestSessionKeystore.cpp +++ b/src/crypto/tests/TestSessionKeystore.cpp @@ -18,15 +18,16 @@ #include "AES_CCM_128_test_vectors.h" +#include + #include #include +#include #include #include #include #include -#include - #if CHIP_CRYPTO_PSA #include #endif diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 331d61129b9daf..7f03a9690b8e61 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -14,8 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#import -#import +#import #import "MTRAttributeTLVValueDecoder_Internal.h" #import "MTRBaseDevice_Internal.h" @@ -31,31 +30,32 @@ #import "MTRLogging_Internal.h" #import "MTRMetricKeys.h" #import "MTRSetupPayload_Internal.h" +#import "MTRUtilities.h" #import "NSDataSpanConversion.h" #import "NSStringSpanConversion.h" #import "zap-generated/MTRCommandPayloads_Internal.h" -#include "app/ConcreteAttributePath.h" -#include "app/ConcreteCommandPath.h" -#include "app/ConcreteEventPath.h" -#include "app/StatusResponse.h" -#include "lib/core/CHIPError.h" -#include "lib/core/DataModelTypes.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include +#import "app/ConcreteAttributePath.h" +#import "app/ConcreteCommandPath.h" +#import "app/ConcreteEventPath.h" +#import "app/StatusResponse.h" +#import "lib/core/CHIPError.h" +#import "lib/core/DataModelTypes.h" + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +#import using namespace chip; using namespace chip::app; @@ -2290,8 +2290,9 @@ + (MTRAttributeRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)end - (BOOL)isEqualToAttributeRequestPath:(MTRAttributeRequestPath *)path { - return [_endpoint isEqualToNumber:path.endpoint] && [_cluster isEqualToNumber:path.cluster] && - [_attribute isEqualToNumber:path.attribute]; + return MTREqualObjects(_endpoint, path.endpoint) + && MTREqualObjects(_cluster, path.cluster) + && MTREqualObjects(_attribute, path.attribute); } - (BOOL)isEqual:(id)object @@ -2362,8 +2363,9 @@ + (MTREventRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)endpoin - (BOOL)isEqualToEventRequestPath:(MTREventRequestPath *)path { - return - [_endpoint isEqualToNumber:path.endpoint] && [_cluster isEqualToNumber:path.cluster] && [_event isEqualToNumber:path.event]; + return MTREqualObjects(_endpoint, path.endpoint) + && MTREqualObjects(_cluster, path.cluster) + && MTREqualObjects(_event, path.event); } - (BOOL)isEqual:(id)object @@ -2432,7 +2434,8 @@ ConcreteClusterPath path(static_cast([endpointID unsignedShort - (BOOL)isEqualToClusterPath:(MTRClusterPath *)clusterPath { - return [_endpoint isEqualToNumber:clusterPath.endpoint] && [_cluster isEqualToNumber:clusterPath.cluster]; + return MTREqualObjects(_endpoint, clusterPath.endpoint) + && MTREqualObjects(_cluster, clusterPath.cluster); } - (BOOL)isEqual:(id)object @@ -2520,7 +2523,7 @@ ConcreteDataAttributePath path(static_cast([endpointID unsigne - (BOOL)isEqualToAttributePath:(MTRAttributePath *)attributePath { - return [self isEqualToClusterPath:attributePath] && [_attribute isEqualToNumber:attributePath.attribute]; + return [self isEqualToClusterPath:attributePath] && MTREqualObjects(_attribute, attributePath.attribute); } - (BOOL)isEqual:(id)object @@ -2613,7 +2616,7 @@ ConcreteEventPath path(static_cast([endpointID unsignedShortVa - (BOOL)isEqualToEventPath:(MTREventPath *)eventPath { - return [self isEqualToClusterPath:eventPath] && [_event isEqualToNumber:eventPath.event]; + return [self isEqualToClusterPath:eventPath] && MTREqualObjects(_event, eventPath.event); } - (BOOL)isEqual:(id)object @@ -2703,7 +2706,7 @@ ConcreteCommandPath path(static_cast([endpointID unsignedShort - (BOOL)isEqualToCommandPath:(MTRCommandPath *)commandPath { - return [self isEqualToClusterPath:commandPath] && [_command isEqualToNumber:commandPath.command]; + return [self isEqualToClusterPath:commandPath] && MTREqualObjects(_command, 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/MTRDemuxingStorage.mm b/src/darwin/Framework/CHIP/MTRDemuxingStorage.mm index 1521a8c54f6726..4ce1a3a93a8f72 100644 --- a/src/darwin/Framework/CHIP/MTRDemuxingStorage.mm +++ b/src/darwin/Framework/CHIP/MTRDemuxingStorage.mm @@ -144,6 +144,8 @@ static bool IsMemoryOnlyGlobalKey(NSString * key) // We do not expect to see the "g/a/*" keys for attribute values. + // We do not expect to see the "g/sa/*" keys for attribute values. + // We do not expect to see the "g/bt" and "g/bt/*" keys for the binding // table. @@ -162,6 +164,9 @@ static bool IsMemoryOnlyGlobalKey(NSString * key) // We do not expect to see the "g/icd/cic" key; that's only used for an ICD // that sends check-in messages. + // We do not expect to see the "g/icdfl" key; that's only used by + // DefaultICDClientStorage, which Matter.framework does not use. + return false; } @@ -215,6 +220,9 @@ static bool IsMemoryOnlyIndexSpecificKey(NSString * key) // We do not expect to see the "e/*" scenes keys. + // We do not epect to see the "icdc" or "icdk" keys, since those are only + // used by DefaultICDClientStorage, which Matter.framework does not use. + return false; } 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..93f96398b51c2f 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -15,7 +15,7 @@ * limitations under the License. */ -#import +#import #import #import "MTRAsyncWorkQueue.h" @@ -39,19 +39,20 @@ #import "MTRMetricsCollector.h" #import "MTRTimeUtils.h" #import "MTRUnfairLock.h" +#import "MTRUtilities.h" #import "zap-generated/MTRCommandPayloads_Internal.h" -#include "lib/core/CHIPError.h" -#include "lib/core/DataModelTypes.h" -#include -#include +#import "lib/core/CHIPError.h" +#import "lib/core/DataModelTypes.h" +#import +#import -#include -#include -#include -#include -#include -#include +#import +#import +#import +#import +#import +#import typedef void (^MTRDeviceAttributeReportHandler)(NSArray * _Nonnull); @@ -60,6 +61,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 +337,8 @@ - (id)copyWithZone:(NSZone *)zone - (BOOL)isEqualToClusterData:(MTRDeviceClusterData *)otherClusterData { - return [_dataVersion isEqual:otherClusterData.dataVersion] && [_attributes isEqual:otherClusterData.attributes]; + return MTREqualObjects(_dataVersion, otherClusterData.dataVersion) + && MTREqualObjects(_attributes, otherClusterData.attributes); } - (BOOL)isEqual:(id)object @@ -536,6 +541,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 +804,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 +849,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 +1308,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 +1317,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 +1343,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 +1393,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 +1401,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 +2265,7 @@ - (void)_createDataVersionFilterListFromDictionary:(NSDictionary_lock); + if (self->_currentSubscriptionCallback) { + self->_currentSubscriptionCallback->ClearCachedAttributeState(static_cast(endpoint.unsignedLongLongValue)); + } + } errorHandler:nil]; } } @@ -3449,6 +3470,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 +3494,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 @@ -3625,7 +3669,9 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray 0) { + MTR_LOG("%@ report from reported values %@", self, attributePathsToReport); + } return attributesToReport; } 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/MTRDeviceStorageBehaviorConfiguration.mm b/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration.mm index 4522c7e69b4ad6..6afa2358c83b06 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration.mm @@ -75,7 +75,7 @@ - (void)checkValuesAndResetToDefaultIfNecessary // Sanity check all the values, and if any is out of range, reset to default values if ((_reportToPersistenceDelayTime <= 0) || (_reportToPersistenceDelayTimeMax <= 0) || (_reportToPersistenceDelayTimeMax < _reportToPersistenceDelayTime) || (_recentReportTimesMaxCount < 2) || (_timeBetweenReportsTooShortThreshold <= 0) || (_timeBetweenReportsTooShortMinThreshold <= 0) || (_timeBetweenReportsTooShortMinThreshold > _timeBetweenReportsTooShortThreshold) || (_reportToPersistenceDelayMaxMultiplier <= 1) || (_deviceReportingExcessivelyIntervalThreshold <= 0)) { - MTR_LOG_ERROR("%@ storage behavior: MTRDeviceStorageBehaviorConfiguration values out of bounds - resetting to default", self); + MTR_LOG("%@ storage behavior: MTRDeviceStorageBehaviorConfiguration values out of bounds - resetting to default", self); _reportToPersistenceDelayTime = kReportToPersistenceDelayTimeDefault; _reportToPersistenceDelayTimeMax = kReportToPersistenceDelayTimeMaxDefault; 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/MTRUtilities.mm b/src/darwin/Framework/CHIP/MTRUtilities.mm index de85b498626495..e9698ab24d0b41 100644 --- a/src/darwin/Framework/CHIP/MTRUtilities.mm +++ b/src/darwin/Framework/CHIP/MTRUtilities.mm @@ -19,5 +19,16 @@ BOOL MTREqualObjects(id _Nullable a, id _Nullable b) { - return (a == nil) ? (b == nil) : [a isEqual:b]; + // Check if A is nil, and return based on B being nil (or not) + if (a == nil) { + return b == nil; + } + + // If B is nil at this point, we're not equal + if (b == nil) { + return NO; + } + + // Otherwise work on equality, given that we're both non nil + return [a isEqual:b]; } 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..87b96a713cf814 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; @@ -3398,6 +3443,45 @@ static BOOL AttributeIsSpecifiedInEnergyEVSEModeCluster(AttributeId aAttributeId } } } +static BOOL AttributeIsSpecifiedInWaterHeaterModeCluster(AttributeId aAttributeId) +{ + using namespace Clusters::WaterHeaterMode; + switch (aAttributeId) { + case Attributes::SupportedModes::Id: { + return YES; + } + case Attributes::CurrentMode::Id: { + return YES; + } + case Attributes::StartUpMode::Id: { + return YES; + } + case Attributes::OnMode::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 AttributeIsSpecifiedInDeviceEnergyManagementModeCluster(AttributeId aAttributeId) { using namespace Clusters::DeviceEnergyManagementMode; @@ -5951,6 +6035,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 +6978,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); } @@ -6885,6 +7002,9 @@ BOOL MTRAttributeIsSpecified(ClusterId aClusterId, AttributeId aAttributeId) case Clusters::EnergyEvseMode::Id: { return AttributeIsSpecifiedInEnergyEVSEModeCluster(aAttributeId); } + case Clusters::WaterHeaterMode::Id: { + return AttributeIsSpecifiedInWaterHeaterModeCluster(aAttributeId); + } case Clusters::DeviceEnergyManagementMode::Id: { return AttributeIsSpecifiedInDeviceEnergyManagementModeCluster(aAttributeId); } @@ -7017,6 +7137,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..96f5a211636050 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; @@ -9741,6 +9819,114 @@ static id _Nullable DecodeAttributeValueForEnergyEVSEModeCluster(AttributeId aAt *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; return nil; } +static id _Nullable DecodeAttributeValueForWaterHeaterModeCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::WaterHeaterMode; + switch (aAttributeId) { + case Attributes::SupportedModes::Id: { + using TypeInfo = Attributes::SupportedModes::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSArray * _Nonnull value; + { // Scope for our temporary variables + auto * array_0 = [NSMutableArray new]; + auto iter_0 = cppValue.begin(); + while (iter_0.Next()) { + auto & entry_0 = iter_0.GetValue(); + MTRWaterHeaterModeClusterModeOptionStruct * newElement_0; + newElement_0 = [MTRWaterHeaterModeClusterModeOptionStruct new]; + newElement_0.label = AsString(entry_0.label); + if (newElement_0.label == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + newElement_0.mode = [NSNumber numberWithUnsignedChar:entry_0.mode]; + { // Scope for our temporary variables + auto * array_2 = [NSMutableArray new]; + auto iter_2 = entry_0.modeTags.begin(); + while (iter_2.Next()) { + auto & entry_2 = iter_2.GetValue(); + MTRWaterHeaterModeClusterModeTagStruct * newElement_2; + newElement_2 = [MTRWaterHeaterModeClusterModeTagStruct new]; + if (entry_2.mfgCode.HasValue()) { + newElement_2.mfgCode = [NSNumber numberWithUnsignedShort:chip::to_underlying(entry_2.mfgCode.Value())]; + } else { + newElement_2.mfgCode = nil; + } + newElement_2.value = [NSNumber numberWithUnsignedShort:entry_2.value]; + [array_2 addObject:newElement_2]; + } + CHIP_ERROR err = iter_2.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + newElement_0.modeTags = array_2; + } + [array_0 addObject:newElement_0]; + } + CHIP_ERROR err = iter_0.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + value = array_0; + } + return value; + } + case Attributes::CurrentMode::Id: { + using TypeInfo = Attributes::CurrentMode::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::StartUpMode::Id: { + using TypeInfo = Attributes::StartUpMode::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + value = [NSNumber numberWithUnsignedChar:cppValue.Value()]; + } + return value; + } + case Attributes::OnMode::Id: { + using TypeInfo = Attributes::OnMode::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + value = [NSNumber numberWithUnsignedChar:cppValue.Value()]; + } + return value; + } + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + return nil; +} static id _Nullable DecodeAttributeValueForDeviceEnergyManagementModeCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::DeviceEnergyManagementMode; @@ -16864,6 +17050,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 +20138,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); } @@ -19950,6 +20162,9 @@ id _Nullable MTRDecodeAttributeValue(const ConcreteAttributePath & aPath, TLV::T case Clusters::EnergyEvseMode::Id: { return DecodeAttributeValueForEnergyEVSEModeCluster(aPath.mAttributeId, aReader, aError); } + case Clusters::WaterHeaterMode::Id: { + return DecodeAttributeValueForWaterHeaterModeCluster(aPath.mAttributeId, aReader, aError); + } case Clusters::DeviceEnergyManagementMode::Id: { return DecodeAttributeValueForDeviceEnergyManagementModeCluster(aPath.mAttributeId, aReader, aError); } @@ -20082,6 +20297,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..181d0c70408b24 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 @@ -8419,6 +8531,103 @@ MTR_PROVISIONALLY_AVAILABLE @end +/** + * Cluster Water Heater Mode + * + * Attributes and commands for selecting a mode from a list of supported options. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRBaseClusterWaterHeaterMode : MTRGenericBaseCluster + +/** + * Command ChangeToMode + * + * This command is used to change device modes. + On receipt of this command the device SHALL respond with a ChangeToModeResponse command. + */ +- (void)changeToModeWithParams:(MTRWaterHeaterModeClusterChangeToModeParams *)params completion:(void (^)(MTRWaterHeaterModeClusterChangeToModeResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeSupportedModesWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeSupportedModesWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeSupportedModesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeCurrentModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeCurrentModeWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeCurrentModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeStartUpModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeStartUpModeWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeStartUpModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeOnModeWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeOnModeWithClusterStateCache:(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 MTRBaseClusterWaterHeaterMode (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 Device Energy Management Mode * @@ -14867,6 +15076,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 +18520,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 +18776,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) { @@ -18510,6 +18826,16 @@ typedef NS_OPTIONS(uint32_t, MTREnergyEVSEModeFeature) { MTREnergyEVSEModeFeatureOnOff MTR_PROVISIONALLY_AVAILABLE = 0x1, } MTR_PROVISIONALLY_AVAILABLE; +typedef NS_ENUM(uint16_t, MTRWaterHeaterModeModeTag) { + MTRWaterHeaterModeModeTagOff MTR_PROVISIONALLY_AVAILABLE = 0x4000, + MTRWaterHeaterModeModeTagManual MTR_PROVISIONALLY_AVAILABLE = 0x4001, + MTRWaterHeaterModeModeTagTimed MTR_PROVISIONALLY_AVAILABLE = 0x4002, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_OPTIONS(uint32_t, MTRWaterHeaterModeFeature) { + MTRWaterHeaterModeFeatureOnOff MTR_PROVISIONALLY_AVAILABLE = 0x1, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_ENUM(uint16_t, MTRDeviceEnergyManagementModeModeTag) { MTRDeviceEnergyManagementModeModeTagNoOptimization MTR_PROVISIONALLY_AVAILABLE = 0x4000, MTRDeviceEnergyManagementModeModeTagDeviceOptimization MTR_PROVISIONALLY_AVAILABLE = 0x4001, @@ -20581,6 +20907,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..6a15e501af9a7d 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 @@ -55374,6 +55863,461 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @end +@implementation MTRBaseClusterWaterHeaterMode + +- (void)changeToModeWithParams:(MTRWaterHeaterModeClusterChangeToModeParams *)params completion:(void (^)(MTRWaterHeaterModeClusterChangeToModeResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRWaterHeaterModeClusterChangeToModeParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WaterHeaterMode::Commands::ChangeToMode::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRWaterHeaterModeClusterChangeToModeResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)readAttributeSupportedModesWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::SupportedModes::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeSupportedModesWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterMode::Attributes::SupportedModes::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeSupportedModesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::SupportedModes::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeCurrentModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::CurrentMode::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeCurrentModeWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterMode::Attributes::CurrentMode::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeCurrentModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::CurrentMode::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeStartUpModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::StartUpMode::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeStartUpModeWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; +} +- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = WaterHeaterMode::Attributes::StartUpMode::TypeInfo; + TypeInfo::Type cppValue; + if (value == nil) { + cppValue.SetNull(); + } else { + auto & nonNullValue_0 = cppValue.SetNonNull(); + nonNullValue_0 = value.unsignedCharValue; + } + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeStartUpModeWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterMode::Attributes::StartUpMode::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeStartUpModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::StartUpMode::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::OnMode::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeOnModeWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; +} +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = WaterHeaterMode::Attributes::OnMode::TypeInfo; + TypeInfo::Type cppValue; + if (value == nil) { + cppValue.SetNull(); + } else { + auto & nonNullValue_0 = cppValue.SetNonNull(); + nonNullValue_0 = value.unsignedCharValue; + } + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeOnModeWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterMode::Attributes::OnMode::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::OnMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::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 = WaterHeaterMode::Attributes::ClusterRevision::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +@end + @implementation MTRBaseClusterDeviceEnergyManagementMode - (void)changeToModeWithParams:(MTRDeviceEnergyManagementModeClusterChangeToModeParams *)params completion:(void (^)(MTRDeviceEnergyManagementModeClusterChangeToModeResponseParams * _Nullable data, NSError * _Nullable error))completion @@ -104178,6 +105122,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..445404818a9573 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, @@ -158,6 +159,7 @@ typedef NS_ENUM(uint32_t, MTRClusterIDType) { MTRClusterIDTypeEnergyPreferenceID MTR_PROVISIONALLY_AVAILABLE = 0x0000009B, MTRClusterIDTypePowerTopologyID MTR_PROVISIONALLY_AVAILABLE = 0x0000009C, MTRClusterIDTypeEnergyEVSEModeID MTR_PROVISIONALLY_AVAILABLE = 0x0000009D, + MTRClusterIDTypeWaterHeaterModeID MTR_PROVISIONALLY_AVAILABLE = 0x0000009E, MTRClusterIDTypeDeviceEnergyManagementModeID MTR_PROVISIONALLY_AVAILABLE = 0x0000009F, MTRClusterIDTypeDoorLockID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000101, MTRClusterIDTypeWindowCoveringID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000102, @@ -202,6 +204,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 +2627,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, @@ -2732,6 +2749,18 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterEnergyEVSEModeAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterEnergyEVSEModeAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster WaterHeaterMode attributes + MTRAttributeIDTypeClusterWaterHeaterModeAttributeSupportedModesID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeCurrentModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeStartUpModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeOnModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster DeviceEnergyManagementMode attributes MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeSupportedModesID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeCurrentModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, @@ -4395,7 +4424,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 +4888,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 +6364,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, @@ -6361,6 +6403,10 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterEnergyEVSEModeCommandChangeToModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRCommandIDTypeClusterEnergyEVSEModeCommandChangeToModeResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + // Cluster WaterHeaterMode commands + MTRCommandIDTypeClusterWaterHeaterModeCommandChangeToModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRCommandIDTypeClusterWaterHeaterModeCommandChangeToModeResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + // Cluster DeviceEnergyManagementMode commands MTRCommandIDTypeClusterDeviceEnergyManagementModeCommandChangeToModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRCommandIDTypeClusterDeviceEnergyManagementModeCommandChangeToModeResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, @@ -6641,9 +6687,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 +6913,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 +7473,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..777f3c0c3ba164 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; @@ -240,6 +243,9 @@ case MTRClusterIDTypeEnergyEVSEModeID: result = @"EnergyEVSEMode"; break; + case MTRClusterIDTypeWaterHeaterModeID: + result = @"WaterHeaterMode"; + break; case MTRClusterIDTypeDeviceEnergyManagementModeID: result = @"DeviceEnergyManagementMode"; break; @@ -372,6 +378,9 @@ case MTRClusterIDTypeContentAppObserverID: result = @"ContentAppObserver"; break; + case MTRClusterIDTypeCommissionerControlID: + result = @"CommissionerControl"; + break; case MTRClusterIDTypeElectricalMeasurementID: result = @"ElectricalMeasurement"; break; @@ -4310,6 +4319,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) { @@ -4756,6 +4823,56 @@ break; } + case MTRClusterIDTypeWaterHeaterModeID: + + switch (attributeID) { + + // Cluster WaterHeaterMode attributes + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeSupportedModesID: + result = @"SupportedModes"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeCurrentModeID: + result = @"CurrentMode"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeStartUpModeID: + result = @"StartUpMode"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeOnModeID: + result = @"OnMode"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeGeneratedCommandListID: + result = @"GeneratedCommandList"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeAcceptedCommandListID: + result = @"AcceptedCommandList"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeEventListID: + result = @"EventList"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeAttributeListID: + result = @"AttributeList"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeFeatureMapID: + result = @"FeatureMap"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeClusterRevisionID: + result = @"ClusterRevision"; + break; + + default: + result = [NSString stringWithFormat:@"", attributeID]; + break; + } + case MTRClusterIDTypeDeviceEnergyManagementModeID: switch (attributeID) { @@ -8072,6 +8189,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..530ffcc58e2808 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. @@ -3968,6 +4021,56 @@ MTR_PROVISIONALLY_AVAILABLE @end +/** + * Cluster Water Heater Mode + * Attributes and commands for selecting a mode from a list of supported options. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRClusterWaterHeaterMode : MTRGenericCluster + +- (void)changeToModeWithParams:(MTRWaterHeaterModeClusterChangeToModeParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRWaterHeaterModeClusterChangeToModeResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeSupportedModesWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeCurrentModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeStartUpModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _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 MTRClusterWaterHeaterMode (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 Device Energy Management Mode * Attributes and commands for selecting a mode from a list of supported options. @@ -6895,6 +6998,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..a753bca9616931 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 @@ -10556,6 +10678,109 @@ - (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueD @end +@implementation MTRClusterWaterHeaterMode + +- (void)changeToModeWithParams:(MTRWaterHeaterModeClusterChangeToModeParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRWaterHeaterModeClusterChangeToModeResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRWaterHeaterModeClusterChangeToModeParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WaterHeaterMode::Commands::ChangeToMode::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRWaterHeaterModeClusterChangeToModeResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (NSDictionary * _Nullable)readAttributeSupportedModesWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeSupportedModesID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeCurrentModeWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeCurrentModeID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeStartUpModeWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeStartUpModeID) params:params]; +} + +- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeStartUpModeWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeStartUpModeID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + +- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeOnModeID) params:params]; +} + +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeOnModeWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeOnModeID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeGeneratedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeAcceptedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeEventListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeAttributeListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeFeatureMapID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeClusterRevisionID) params:params]; +} + +@end + @implementation MTRClusterDeviceEnergyManagementMode - (void)changeToModeWithParams:(MTRDeviceEnergyManagementModeClusterChangeToModeParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRDeviceEnergyManagementModeClusterChangeToModeResponseParams * _Nullable data, NSError * _Nullable error))completion @@ -19784,6 +20009,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..7c30f13fbe7044 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 @@ -6110,6 +6178,57 @@ MTR_PROVISIONALLY_AVAILABLE error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWaterHeaterModeClusterChangeToModeParams : NSObject + +@property (nonatomic, copy, getter=getNewMode) NSNumber * _Nonnull newMode 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 MTRWaterHeaterModeClusterChangeToModeResponseParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull status MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSString * _Nullable statusText MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRWaterHeaterModeClusterChangeToModeResponseParams 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_PROVISIONALLY_AVAILABLE @interface MTRDeviceEnergyManagementModeClusterChangeToModeParams : NSObject @@ -10737,6 +10856,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..441fc5cb8361cf 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 { @@ -17393,7 +17590,7 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::EnergyEv @end -@implementation MTRDeviceEnergyManagementModeClusterChangeToModeParams +@implementation MTRWaterHeaterModeClusterChangeToModeParams - (instancetype)init { if (self = [super init]) { @@ -17407,7 +17604,7 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRDeviceEnergyManagementModeClusterChangeToModeParams alloc] init]; + auto other = [[MTRWaterHeaterModeClusterChangeToModeParams alloc] init]; other.newMode = self.newMode; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; @@ -17424,11 +17621,11 @@ - (NSString *)description @end -@implementation MTRDeviceEnergyManagementModeClusterChangeToModeParams (InternalMethods) +@implementation MTRWaterHeaterModeClusterChangeToModeParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::DeviceEnergyManagementMode::Commands::ChangeToMode::Type encodableStruct; + chip::app::Clusters::WaterHeaterMode::Commands::ChangeToMode::Type encodableStruct; ListFreer listFreer; { encodableStruct.newMode = self.newMode.unsignedCharValue; @@ -17472,7 +17669,7 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRDeviceEnergyManagementModeClusterChangeToModeResponseParams +@implementation MTRWaterHeaterModeClusterChangeToModeResponseParams - (instancetype)init { if (self = [super init]) { @@ -17486,7 +17683,7 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRDeviceEnergyManagementModeClusterChangeToModeResponseParams alloc] init]; + auto other = [[MTRWaterHeaterModeClusterChangeToModeResponseParams alloc] init]; other.status = self.status; other.statusText = self.statusText; @@ -17507,7 +17704,7 @@ - (nullable instancetype)initWithResponseValue:(NSDictionary *)r return nil; } - using DecodableType = chip::app::Clusters::DeviceEnergyManagementMode::Commands::ChangeToModeResponse::DecodableType; + using DecodableType = chip::app::Clusters::WaterHeaterMode::Commands::ChangeToModeResponse::DecodableType; chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue clusterID:DecodableType::GetClusterId() commandID:DecodableType::GetCommandId() @@ -17542,9 +17739,9 @@ - (nullable instancetype)initWithResponseValue:(NSDictionary *)r @end -@implementation MTRDeviceEnergyManagementModeClusterChangeToModeResponseParams (InternalMethods) +@implementation MTRWaterHeaterModeClusterChangeToModeResponseParams (InternalMethods) -- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::DeviceEnergyManagementMode::Commands::ChangeToModeResponse::DecodableType &)decodableStruct +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::WaterHeaterMode::Commands::ChangeToModeResponse::DecodableType &)decodableStruct { { self.status = [NSNumber numberWithUnsignedChar:decodableStruct.status]; @@ -17565,12 +17762,12 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::DeviceEn @end -@implementation MTRDoorLockClusterLockDoorParams +@implementation MTRDeviceEnergyManagementModeClusterChangeToModeParams - (instancetype)init { if (self = [super init]) { - _pinCode = nil; + _newMode = @(0); _timedInvokeTimeoutMs = nil; _serverSideProcessingTimeout = nil; } @@ -17579,9 +17776,9 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRDoorLockClusterLockDoorParams alloc] init]; + auto other = [[MTRDeviceEnergyManagementModeClusterChangeToModeParams alloc] init]; - other.pinCode = self.pinCode; + other.newMode = self.newMode; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -17590,23 +17787,20 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: pinCode:%@; >", NSStringFromClass([self class]), [_pinCode base64EncodedStringWithOptions:0]]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: newMode:%@; >", NSStringFromClass([self class]), _newMode]; return descriptionString; } @end -@implementation MTRDoorLockClusterLockDoorParams (InternalMethods) +@implementation MTRDeviceEnergyManagementModeClusterChangeToModeParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::DoorLock::Commands::LockDoor::Type encodableStruct; + chip::app::Clusters::DeviceEnergyManagementMode::Commands::ChangeToMode::Type encodableStruct; ListFreer listFreer; { - if (self.pinCode != nil) { - auto & definedValue_0 = encodableStruct.PINCode.Emplace(); - definedValue_0 = AsByteSpan(self.pinCode); - } + encodableStruct.newMode = self.newMode.unsignedCharValue; } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); @@ -17647,68 +17841,243 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRDoorLockClusterUnlockDoorParams +@implementation MTRDeviceEnergyManagementModeClusterChangeToModeResponseParams - (instancetype)init { if (self = [super init]) { - _pinCode = nil; - _timedInvokeTimeoutMs = nil; - _serverSideProcessingTimeout = nil; + _status = @(0); + + _statusText = nil; } return self; } - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRDoorLockClusterUnlockDoorParams alloc] init]; + auto other = [[MTRDeviceEnergyManagementModeClusterChangeToModeResponseParams alloc] init]; - other.pinCode = self.pinCode; - other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; - other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + other.status = self.status; + other.statusText = self.statusText; return other; } - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: pinCode:%@; >", NSStringFromClass([self class]), [_pinCode base64EncodedStringWithOptions:0]]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: status:%@; statusText:%@; >", NSStringFromClass([self class]), _status, _statusText]; return descriptionString; } -@end - -@implementation MTRDoorLockClusterUnlockDoorParams (InternalMethods) - -- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error { - chip::app::Clusters::DoorLock::Commands::UnlockDoor::Type encodableStruct; - ListFreer listFreer; - { - if (self.pinCode != nil) { - auto & definedValue_0 = encodableStruct.PINCode.Emplace(); - definedValue_0 = AsByteSpan(self.pinCode); - } + if (!(self = [super init])) { + return nil; } - auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + using DecodableType = chip::app::Clusters::DeviceEnergyManagementMode::Commands::ChangeToModeResponse::DecodableType; + chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue + clusterID:DecodableType::GetClusterId() + commandID:DecodableType::GetCommandId() + error:error]; if (buffer.IsNull()) { - return CHIP_ERROR_NO_MEMORY; + return nil; } - 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)); + chip::TLV::TLVReader reader; + reader.Init(buffer->Start(), buffer->DataLength()); - reader.Init(std::move(buffer)); - return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); -} + 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; + } + } + } -- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error + 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 MTRDeviceEnergyManagementModeClusterChangeToModeResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::DeviceEnergyManagementMode::Commands::ChangeToModeResponse::DecodableType &)decodableStruct +{ + { + self.status = [NSNumber numberWithUnsignedChar:decodableStruct.status]; + } + { + if (decodableStruct.statusText.HasValue()) { + self.statusText = AsString(decodableStruct.statusText.Value()); + if (self.statusText == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.statusText = nil; + } + } + return CHIP_NO_ERROR; +} + +@end + +@implementation MTRDoorLockClusterLockDoorParams +- (instancetype)init +{ + if (self = [super init]) { + + _pinCode = nil; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRDoorLockClusterLockDoorParams alloc] init]; + + other.pinCode = self.pinCode; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: pinCode:%@; >", NSStringFromClass([self class]), [_pinCode base64EncodedStringWithOptions:0]]; + return descriptionString; +} + +@end + +@implementation MTRDoorLockClusterLockDoorParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::DoorLock::Commands::LockDoor::Type encodableStruct; + ListFreer listFreer; + { + if (self.pinCode != nil) { + auto & definedValue_0 = encodableStruct.PINCode.Emplace(); + definedValue_0 = AsByteSpan(self.pinCode); + } + } + + 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 MTRDoorLockClusterUnlockDoorParams +- (instancetype)init +{ + if (self = [super init]) { + + _pinCode = nil; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRDoorLockClusterUnlockDoorParams alloc] init]; + + other.pinCode = self.pinCode; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: pinCode:%@; >", NSStringFromClass([self class]), [_pinCode base64EncodedStringWithOptions:0]]; + return descriptionString; +} + +@end + +@implementation MTRDoorLockClusterUnlockDoorParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::DoorLock::Commands::UnlockDoor::Type encodableStruct; + ListFreer listFreer; + { + if (self.pinCode != nil) { + auto & definedValue_0 = encodableStruct.PINCode.Emplace(); + definedValue_0 = AsByteSpan(self.pinCode); + } + } + + 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]; @@ -30836,6 +31205,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..c229f6cda86db8 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; @@ -1150,6 +1162,18 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRWaterHeaterModeClusterChangeToModeParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRWaterHeaterModeClusterChangeToModeResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::WaterHeaterMode::Commands::ChangeToModeResponse::DecodableType &)decodableStruct; + +@end + @interface MTRDeviceEnergyManagementModeClusterChangeToModeParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; @@ -2008,6 +2032,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..4abe6bf88050bd 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; @@ -692,6 +701,15 @@ static BOOL CommandNeedsTimedInvokeInEnergyEVSEModeCluster(AttributeId aAttribut } } } +static BOOL CommandNeedsTimedInvokeInWaterHeaterModeCluster(AttributeId aAttributeId) +{ + using namespace Clusters::WaterHeaterMode; + switch (aAttributeId) { + default: { + return NO; + } + } +} static BOOL CommandNeedsTimedInvokeInDeviceEnergyManagementModeCluster(AttributeId aAttributeId) { using namespace Clusters::DeviceEnergyManagementMode; @@ -1136,6 +1154,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 +1392,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); } @@ -1386,6 +1416,9 @@ BOOL MTRCommandNeedsTimedInvoke(NSNumber * _Nonnull aClusterID, NSNumber * _Nonn case Clusters::EnergyEvseMode::Id: { return CommandNeedsTimedInvokeInEnergyEVSEModeCluster(commandID); } + case Clusters::WaterHeaterMode::Id: { + return CommandNeedsTimedInvokeInWaterHeaterModeCluster(commandID); + } case Clusters::DeviceEnergyManagementMode::Id: { return CommandNeedsTimedInvokeInDeviceEnergyManagementModeCluster(commandID); } @@ -1518,6 +1551,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..445807b9902bd8 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; } @@ -3276,6 +3306,18 @@ static id _Nullable DecodeEventPayloadForEnergyEVSEModeCluster(EventId aEventId, *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; return nil; } +static id _Nullable DecodeEventPayloadForWaterHeaterModeCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::WaterHeaterMode; + switch (aEventId) { + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + return nil; +} static id _Nullable DecodeEventPayloadForDeviceEnergyManagementModeCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::DeviceEnergyManagementMode; @@ -4416,6 +4458,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 +4888,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); } @@ -4823,6 +4912,9 @@ id _Nullable MTRDecodeEventPayload(const ConcreteEventPath & aPath, TLV::TLVRead case Clusters::EnergyEvseMode::Id: { return DecodeEventPayloadForEnergyEVSEModeCluster(aPath.mEventId, aReader, aError); } + case Clusters::WaterHeaterMode::Id: { + return DecodeEventPayloadForWaterHeaterModeCluster(aPath.mEventId, aReader, aError); + } case Clusters::DeviceEnergyManagementMode::Id: { return DecodeEventPayloadForDeviceEnergyManagementModeCluster(aPath.mEventId, aReader, aError); } @@ -4955,6 +5047,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..dd93b4322ad447 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 @@ -1452,6 +1454,19 @@ MTR_PROVISIONALLY_AVAILABLE @property (nonatomic, copy) NSArray * _Nonnull modeTags MTR_PROVISIONALLY_AVAILABLE; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWaterHeaterModeClusterModeTagStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nullable mfgCode MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull value MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWaterHeaterModeClusterModeOptionStruct : NSObject +@property (nonatomic, copy) NSString * _Nonnull label MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull mode MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSArray * _Nonnull modeTags MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_PROVISIONALLY_AVAILABLE @interface MTRDeviceEnergyManagementModeClusterModeTagStruct : NSObject @property (nonatomic, copy) NSNumber * _Nullable mfgCode MTR_PROVISIONALLY_AVAILABLE; @@ -2037,6 +2052,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..6fe345c0621baf 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; } @@ -6002,6 +6008,69 @@ - (NSString *)description @end +@implementation MTRWaterHeaterModeClusterModeTagStruct +- (instancetype)init +{ + if (self = [super init]) { + + _mfgCode = nil; + + _value = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRWaterHeaterModeClusterModeTagStruct alloc] init]; + + other.mfgCode = self.mfgCode; + other.value = self.value; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: mfgCode:%@; value:%@; >", NSStringFromClass([self class]), _mfgCode, _value]; + return descriptionString; +} + +@end + +@implementation MTRWaterHeaterModeClusterModeOptionStruct +- (instancetype)init +{ + if (self = [super init]) { + + _label = @""; + + _mode = @(0); + + _modeTags = [NSArray array]; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRWaterHeaterModeClusterModeOptionStruct alloc] init]; + + other.label = self.label; + other.mode = self.mode; + other.modeTags = self.modeTags; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: label:%@; mode:%@; modeTags:%@; >", NSStringFromClass([self class]), _label, _mode, _modeTags]; + return descriptionString; +} + +@end + @implementation MTRDeviceEnergyManagementModeClusterModeTagStruct - (instancetype)init { @@ -8385,6 +8454,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/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index 132ab263cf30f6..da059fc505de8c 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -1898,6 +1898,20 @@ - (void)test020_ReadMultipleAttributes MTRBaseDevice * device = GetConnectedDevice(); dispatch_queue_t queue = dispatch_get_main_queue(); + // Get the list of endpoints from the device. Endpoint 0 we have to add explicitly, since it's + // not in its own PartsList. + XCTestExpectation * descriptorReadExpectation = [self expectationWithDescription:@"read PartsList from endpoint 0"]; + __auto_type * descriptorCluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device endpointID:@(0) queue:queue]; + __block NSMutableArray * endpointList = [NSMutableArray arrayWithObject:@0]; + [descriptorCluster readAttributePartsListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + XCTAssertNil(error); + XCTAssertNotNil(value); + [endpointList addObjectsFromArray:value]; + [descriptorReadExpectation fulfill]; + }]; + + [self waitForExpectations:@[ descriptorReadExpectation ] timeout:kTimeoutInSeconds]; + NSArray * attributePaths = @[ [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@0], [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@1], @@ -2028,8 +2042,7 @@ - (void)test020_ReadMultipleAttributes MTRAttributePath * path = result[@"attributePath"]; if ([path.attribute unsignedIntegerValue] < 4) { XCTAssertEqualObjects(path.cluster, @29); - __auto_type endpoint = [path.endpoint unsignedShortValue]; - XCTAssertTrue(endpoint == 0 || endpoint == 1 || endpoint == 2); + XCTAssertTrue([endpointList containsObject:path.endpoint]); } else { XCTAssertEqualObjects(path.cluster, @40); XCTAssertEqualObjects(path.endpoint, @0); @@ -2041,10 +2054,10 @@ - (void)test020_ReadMultipleAttributes XCTFail("Unexpected result dictionary %@", result); } } - // Our test application has 3 endpoints. We have a descriptor on each one, - // so that's 4 results per endpoint, and we only have Basic Information on - // endpoint 0, so that's 4 more results. - XCTAssertEqual(attributeResultCount, 3 * 4 + 4); + // We have a descriptor on each endpoint, so that's 4 results per endpoint, + // and we only have Basic Information on endpoint 0, so that's 4 more + // results. + XCTAssertEqual(attributeResultCount, endpointList.count * 4 + 4); XCTAssertEqual(eventResultCount, [eventPaths count]); [expectation fulfill]; @@ -2061,11 +2074,11 @@ - (void)test021_ReadMultipleWildcardPathsIncludeUnsupportedAttribute // Read the PartList of descriptor on endpoint 0 to find out how many endpoints there are. XCTestExpectation * descriptorReadExpectation = [self expectationWithDescription:@"read PartsList from endpoint 0"]; __auto_type * descriptorCluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device endpointID:@(0) queue:queue]; - __block size_t endpointCount = 0; + __block NSMutableArray * endpointList = [NSMutableArray arrayWithObject:@0]; [descriptorCluster readAttributePartsListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { XCTAssertNil(error); XCTAssertNotNil(value); - endpointCount = value.count + 1; // Include endpoint 0 + [endpointList addObjectsFromArray:value]; [descriptorReadExpectation fulfill]; }]; @@ -2103,14 +2116,13 @@ - (void)test021_ReadMultipleWildcardPathsIncludeUnsupportedAttribute // and we only have Basic Information on endpoint 0, so that's 4 more // results. Note that there are no results for failAttributeID, because we // used a wildcard path and hence it got ignored. - XCTAssertEqual(resultArray.count, endpointCount * 4 + 4); + XCTAssertEqual(resultArray.count, endpointList.count * 4 + 4); for (NSDictionary * result in resultArray) { MTRAttributePath * path = result[@"attributePath"]; if ([path.attribute unsignedIntegerValue] < 4) { XCTAssertEqualObjects(path.cluster, @29); - __auto_type endpoint = [path.endpoint unsignedShortValue]; - XCTAssertTrue(endpoint == 0 || endpoint == 1 || endpoint == 2); + XCTAssertTrue([endpointList containsObject:path.endpoint]); } else { XCTAssertEqualObjects(path.cluster, @40); XCTAssertEqualObjects(path.endpoint, @0); @@ -3171,7 +3183,7 @@ + (void)checkAttributeReportTriggersConfigurationChanged:(MTRAttributeIDType)att XCTestExpectation * gotAttributeReportExpectation = [testcase expectationWithDescription:@"Attribute report has been received"]; XCTestExpectation * gotAttributeReportEndExpectation = [testcase expectationWithDescription:@"Attribute report has ended"]; - XCTestExpectation * deviceConfigurationChangedExpectation = [testcase expectationWithDescription:@"Device configuration changed was receieved"]; + XCTestExpectation * deviceConfigurationChangedExpectation = [testcase expectationWithDescription:@"Device configuration changed was received"]; deviceConfigurationChangedExpectation.inverted = !expectConfigurationChanged; __block unsigned attributeReportsReceived = 0; @@ -3252,13 +3264,22 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged // attribute list and cluster revision for the Identify cluster, accepted commands list for oven cavity operational state ID cluster and // feature map for groups ID cluster. __block NSNumber * dataVersionForPartsList; + __block NSMutableArray *> * valueForPartsList; + __block NSNumber * endpointForPartsList; __block NSNumber * dataVersionForDeviceTypesList; + __block NSNumber * endpointForDeviceTypeList; __block NSNumber * dataVersionForServerList; + __block NSNumber * endpointForServerList; __block NSNumber * dataVersionForAcceptedCommandList; + __block NSNumber * endpointForAcceptedCommandList; __block NSNumber * dataVersionForAttributeList; + __block NSNumber * endpointForAttributeList; __block NSNumber * dataVersionForClusterRevision; + __block NSNumber * endpointForClusterRevision; __block NSNumber * dataVersionForFeatureMap; + __block NSNumber * endpointForFeatureMap; __block NSNumber * dataVersionForPowerConfigurationSources; + __block NSNumber * endpointForPowerConfigurationSources; delegate.onAttributeDataReceived = ^(NSArray *> * attributeReport) { attributeReportsReceived += attributeReport.count; @@ -3268,20 +3289,24 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged MTRAttributePath * attributePath = attributeDict[MTRAttributePathKey]; XCTAssertNotNil(attributePath); - if (attributePath.cluster.unsignedLongValue == MTRClusterIDTypeDescriptorID) { + if (attributePath.cluster.unsignedLongValue == MTRClusterIDTypeDescriptorID && attributePath.endpoint.unsignedLongValue == 0) { NSDictionary * data = attributeDict[MTRDataKey]; XCTAssertNotNil(data); switch (attributePath.attribute.unsignedLongValue) { case MTRAttributeIDTypeClusterDescriptorAttributePartsListID: { dataVersionForPartsList = data[MTRDataVersionKey]; + valueForPartsList = [data[MTRValueKey] mutableCopy]; + endpointForPartsList = attributePath.endpoint; break; } case MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID: { dataVersionForDeviceTypesList = data[MTRDataVersionKey]; + endpointForDeviceTypeList = attributePath.endpoint; break; } case MTRAttributeIDTypeClusterDescriptorAttributeServerListID: { dataVersionForServerList = data[MTRDataVersionKey]; + endpointForServerList = attributePath.endpoint; break; } } @@ -3291,10 +3316,12 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged switch (attributePath.attribute.unsignedLongValue) { case MTRAttributeIDTypeGlobalAttributeAttributeListID: { dataVersionForAttributeList = data[MTRDataVersionKey]; + endpointForAttributeList = attributePath.endpoint; break; } case MTRAttributeIDTypeGlobalAttributeClusterRevisionID: { dataVersionForClusterRevision = data[MTRDataVersionKey]; + endpointForClusterRevision = attributePath.endpoint; break; } } @@ -3302,14 +3329,17 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged NSDictionary * data = attributeDict[MTRDataKey]; XCTAssertNotNil(data); dataVersionForAcceptedCommandList = data[MTRDataVersionKey]; + endpointForAcceptedCommandList = attributePath.endpoint; } else if (attributePath.cluster.unsignedLongValue == MTRClusterIDTypeGroupsID && attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeGlobalAttributeFeatureMapID) { NSDictionary * data = attributeDict[MTRDataKey]; XCTAssertNotNil(data); dataVersionForFeatureMap = data[MTRDataVersionKey]; + endpointForFeatureMap = attributePath.endpoint; } else if (attributePath.cluster.unsignedLongValue == MTRClusterIDTypePowerSourceConfigurationID && attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeSourcesID) { NSDictionary * data = attributeDict[MTRDataKey]; XCTAssertNotNil(data); dataVersionForPowerConfigurationSources = data[MTRDataVersionKey]; + endpointForPowerConfigurationSources = attributePath.endpoint; } } }; @@ -3342,37 +3372,30 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged // Test attribute path - endpointId = 0, clusterId = descriptor, attributeId = parts list. dataVersionForPartsList = [NSNumber numberWithUnsignedLongLong:(dataVersionForPartsList.unsignedLongLongValue + 1)]; - NSArray *> * unsignedIntegerArrayValue = @[ - @{ + // Figure out an endpoint ID (not 0) we can add to PartsList. + for (unsigned i = 1; true; ++i) { + __auto_type unsignedIntegerValue = @{ MTRDataKey : @ { MTRTypeKey : MTRUnsignedIntegerValueType, - MTRValueKey : @1, - } - }, - @{ - MTRDataKey : @ { - MTRTypeKey : MTRUnsignedIntegerValueType, - MTRValueKey : @2, + MTRValueKey : @(i), } - }, - @{ - MTRDataKey : @ { - MTRTypeKey : MTRUnsignedIntegerValueType, - MTRValueKey : @3, - } - }, - ]; + }; + if (![valueForPartsList containsObject:unsignedIntegerValue]) { + [valueForPartsList addObject:unsignedIntegerValue]; + break; + } + } NSArray *> * attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributePartsListID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForPartsList clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributePartsListID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForPartsList, MTRTypeKey : MTRArrayValueType, - MTRValueKey : unsignedIntegerArrayValue, + MTRValueKey : valueForPartsList, } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterDescriptorAttributePartsListID clusterId:MTRClusterIDTypeDescriptorID endpointId:@(0) device:device delegate:delegate dataVersion:dataVersionForPartsList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterDescriptorAttributePartsListID clusterId:MTRClusterIDTypeDescriptorID endpointId:endpointForPartsList device:device delegate:delegate dataVersion:dataVersionForPartsList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; // Test attribute path - endpointId = 0, clusterId = descriptor, attributeId = device types list. dataVersionForDeviceTypesList = [NSNumber numberWithUnsignedLongLong:(dataVersionForDeviceTypesList.unsignedLongLongValue + 1)]; @@ -3401,7 +3424,7 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged ]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForDeviceTypeList clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForDeviceTypesList, MTRTypeKey : MTRArrayValueType, @@ -3409,12 +3432,34 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID clusterId:MTRClusterIDTypeDescriptorID endpointId:@(0) device:device delegate:delegate dataVersion:dataVersionForDeviceTypesList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; + // unsignedIntegerArrayValue is used for a variety of tests below. + NSArray *> * unsignedIntegerArrayValue = @[ + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @1, + } + }, + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @2, + } + }, + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @3, + } + }, + ]; + + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID clusterId:MTRClusterIDTypeDescriptorID endpointId:endpointForDeviceTypeList device:device delegate:delegate dataVersion:dataVersionForDeviceTypesList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; // Test attribute path - endpointId = 0, clusterId = descriptor, attributeId = server list. dataVersionForServerList = [NSNumber numberWithUnsignedLongLong:(dataVersionForServerList.unsignedLongLongValue + 1)]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeServerListID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForServerList clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeServerListID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForServerList, MTRTypeKey : MTRArrayValueType, @@ -3422,12 +3467,12 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterDescriptorAttributeServerListID clusterId:MTRClusterIDTypeDescriptorID endpointId:@(0) device:device delegate:delegate dataVersion:dataVersionForServerList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterDescriptorAttributeServerListID clusterId:MTRClusterIDTypeDescriptorID endpointId:endpointForServerList device:device delegate:delegate dataVersion:dataVersionForServerList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; // Test attribute path - endpointId = 1, clusterId = ovencavityoperationalstateID, attributeId = accepted command list. dataVersionForAcceptedCommandList = [NSNumber numberWithUnsignedLongLong:(dataVersionForAcceptedCommandList.unsignedLongLongValue + 1)]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(1) clusterID:@(MTRClusterIDTypeOvenCavityOperationalStateID) attributeID:@(MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForAcceptedCommandList clusterID:@(MTRClusterIDTypeOvenCavityOperationalStateID) attributeID:@(MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForAcceptedCommandList, MTRTypeKey : MTRArrayValueType, @@ -3435,12 +3480,12 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID clusterId:MTRClusterIDTypeOvenCavityOperationalStateID endpointId:@(1) device:device delegate:delegate dataVersion:dataVersionForAcceptedCommandList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID clusterId:MTRClusterIDTypeOvenCavityOperationalStateID endpointId:endpointForAcceptedCommandList device:device delegate:delegate dataVersion:dataVersionForAcceptedCommandList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; // Test attribute path - endpointId = 0, clusterId = identify, attributeId = attribute list. dataVersionForAttributeList = [NSNumber numberWithUnsignedLongLong:(dataVersionForAttributeList.unsignedLongLongValue + 1)]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeGlobalAttributeAttributeListID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForAttributeList clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeGlobalAttributeAttributeListID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForAttributeList, MTRTypeKey : MTRArrayValueType, @@ -3448,12 +3493,12 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeAttributeListID clusterId:MTRClusterIDTypeIdentifyID endpointId:@(0) device:device delegate:delegate dataVersion:dataVersionForAttributeList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeAttributeListID clusterId:MTRClusterIDTypeIdentifyID endpointId:endpointForAttributeList device:device delegate:delegate dataVersion:dataVersionForAttributeList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; // Test attribute path - endpointId = 0, clusterId = identify, attributeId = cluster revision. dataVersionForClusterRevision = [NSNumber numberWithUnsignedLongLong:(dataVersionForClusterRevision.unsignedLongLongValue + 1)]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeGlobalAttributeClusterRevisionID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForClusterRevision clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeGlobalAttributeClusterRevisionID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForClusterRevision, MTRTypeKey : MTRUnsignedIntegerValueType, @@ -3461,12 +3506,12 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeClusterRevisionID clusterId:MTRClusterIDTypeIdentifyID endpointId:@(0) device:device delegate:delegate dataVersion:dataVersionForClusterRevision attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeClusterRevisionID clusterId:MTRClusterIDTypeIdentifyID endpointId:endpointForClusterRevision device:device delegate:delegate dataVersion:dataVersionForClusterRevision attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; // Test attribute path - endpointId = 0, clusterId = groupsID, attributeId = feature map. dataVersionForFeatureMap = [NSNumber numberWithUnsignedLongLong:(dataVersionForFeatureMap.unsignedLongLongValue + 1)]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeGroupsID) attributeID:@(MTRAttributeIDTypeGlobalAttributeFeatureMapID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForFeatureMap clusterID:@(MTRClusterIDTypeGroupsID) attributeID:@(MTRAttributeIDTypeGlobalAttributeFeatureMapID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForFeatureMap, MTRTypeKey : MTRUnsignedIntegerValueType, @@ -3474,12 +3519,12 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeFeatureMapID clusterId:MTRClusterIDTypeGroupsID endpointId:@(0) device:device delegate:delegate dataVersion:dataVersionForFeatureMap attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeFeatureMapID clusterId:MTRClusterIDTypeGroupsID endpointId:endpointForFeatureMap device:device delegate:delegate dataVersion:dataVersionForFeatureMap attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; // Test attribute path that doesn't cause a device configuration changed - endpointId = 1, clusterId = power source configuration, attributeId = sources. dataVersionForPowerConfigurationSources = [NSNumber numberWithUnsignedLongLong:(dataVersionForPowerConfigurationSources.unsignedLongLongValue + 1)]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypePowerSourceConfigurationID) attributeID:@(MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeSourcesID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForPowerConfigurationSources clusterID:@(MTRClusterIDTypePowerSourceConfigurationID) attributeID:@(MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeSourcesID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForPowerConfigurationSources, MTRTypeKey : MTRArrayValueType, @@ -3487,7 +3532,7 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeSourcesID clusterId:MTRClusterIDTypePowerSourceConfigurationID endpointId:@(0) device:device delegate:delegate dataVersion:dataVersionForPowerConfigurationSources attributeReport:attributeReport testcase:self expectConfigurationChanged:NO]; + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeSourcesID clusterId:MTRClusterIDTypePowerSourceConfigurationID endpointId:endpointForPowerConfigurationSources device:device delegate:delegate dataVersion:dataVersionForPowerConfigurationSources attributeReport:attributeReport testcase:self expectConfigurationChanged:NO]; NSArray *> * newUnsignedIntegerArrayValue = @[ @{ @@ -3510,7 +3555,7 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged dataVersionForPowerConfigurationSources = [NSNumber numberWithUnsignedLongLong:(dataVersionForPowerConfigurationSources.unsignedLongLongValue + 1)]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeGlobalAttributeAttributeListID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForAttributeList clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeGlobalAttributeAttributeListID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForAttributeList, MTRTypeKey : MTRArrayValueType, @@ -3518,7 +3563,7 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } }, @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeGroupsID) attributeID:@(MTRAttributeIDTypeGlobalAttributeFeatureMapID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForFeatureMap clusterID:@(MTRClusterIDTypeGroupsID) attributeID:@(MTRAttributeIDTypeGlobalAttributeFeatureMapID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForFeatureMap, MTRTypeKey : MTRUnsignedIntegerValueType, @@ -3526,7 +3571,7 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } }, @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypePowerSourceConfigurationID) attributeID:@(MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeSourcesID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForPowerConfigurationSources clusterID:@(MTRClusterIDTypePowerSourceConfigurationID) attributeID:@(MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeSourcesID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForPowerConfigurationSources, MTRTypeKey : MTRArrayValueType, diff --git a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m index ced79aadb78b82..4c7375c45dd06b 100644 --- a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m +++ b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m @@ -2508,11 +2508,12 @@ - (void)testDataStorageUpdatesWhenRemovingEndpoints __block NSNumber * rootEndpoint = @0; // This test will do the following - - // 1. Get the data version and attribute value of the parts list for endpoint 0 to inject a fake report. The attribute report will delete endpoint 2. + // 1. Get the data version and attribute value of the parts list for endpoint 0 to inject a fake report. + // The injected attribute report will delete endpoint 2. // That should cause the endpoint and its corresponding clusters to be removed from data storage. - // 2. The data store is populated with cluster index and cluster data for endpoints 0, 1 and 2 initially. + // 2. The data store is populated with cluster index and cluster data for the set of endpoints in our test app initially. // 3. After the fake attribute report is injected with deleted endpoint 2, make sure the data store is still populated with cluster index and cluster data - // for endpoints 0 and 1 but not 2. + // for all the other endpoints. __block MTRDeviceDataValueDictionary testDataForPartsList; __block id testClusterDataValueForPartsList; delegate.onAttributeDataReceived = ^(NSArray *> * attributeReport) { @@ -2534,18 +2535,21 @@ - (void)testDataStorageUpdatesWhenRemovingEndpoints }; __block NSMutableDictionary *> * initialClusterIndex = [[NSMutableDictionary alloc] init]; - __block NSMutableArray * testEndpoints; + // Some of the places we get endpoint lists get them from enumerating dictionary keys, which + // means order is not guaranteed. Make sure we compare sets of endpoints, not arrays, to + // account for that. + __block NSSet * testEndpoints; delegate.onReportEnd = ^{ XCTAssertNotNil(dataVersionForPartsList); XCTAssertNotNil(testClusterDataValueForPartsList); - testEndpoints = [self getEndpointArrayFromPartsList:testDataForPartsList forDevice:device]; + testEndpoints = [NSSet setWithArray:[self getEndpointArrayFromPartsList:testDataForPartsList forDevice:device]]; - // Make sure that the cluster data in the data storage is populated with cluster index and cluster data for endpoints 0, 1 and 2. + // Make sure that the cluster data in the data storage is populated with cluster index and cluster data for our endpoints. // We do not need to check _persistedClusterData here. _persistedClusterData will be paged in from storage when needed so // just checking data storage should suffice here. dispatch_sync(self->_storageQueue, ^{ - XCTAssertTrue([[controller.controllerDataStore _fetchEndpointIndexForNodeID:deviceID] isEqualToArray:testEndpoints]); + XCTAssertEqualObjects([NSSet setWithArray:[controller.controllerDataStore _fetchEndpointIndexForNodeID:deviceID]], testEndpoints); // Populate the initialClusterIndex to use as a reference for all cluster paths later. for (NSNumber * endpoint in testEndpoints) { @@ -2568,8 +2572,9 @@ - (void)testDataStorageUpdatesWhenRemovingEndpoints // Inject a fake attribute report deleting endpoint 2 from the parts list at the root endpoint. dataVersionForPartsList = [NSNumber numberWithUnsignedLongLong:(dataVersionForPartsList.unsignedLongLongValue + 1)]; - // Delete endpoint 2 from the attribute value in parts list. + // Delete our to-be-deleted endpoint from the attribute value in parts list. Make sure it's in the list to start with. NSNumber * toBeDeletedEndpoint = @2; + XCTAssertTrue([testEndpoints containsObject:toBeDeletedEndpoint]); id endpointData = @{ MTRDataKey : @ { @@ -2578,6 +2583,7 @@ - (void)testDataStorageUpdatesWhenRemovingEndpoints } }; + XCTAssertTrue([testClusterDataValueForPartsList containsObject:endpointData]); [testClusterDataValueForPartsList removeObject:endpointData]; NSArray *> * attributeReport = @[ @{ @@ -2612,13 +2618,13 @@ - (void)testDataStorageUpdatesWhenRemovingEndpoints delegate.onReportEnd = ^{ XCTAssertNotNil(testClusterDataValueForPartsList); - testEndpoints = [self getEndpointArrayFromPartsList:testDataForPartsList forDevice:device]; + testEndpoints = [NSSet setWithArray:[self getEndpointArrayFromPartsList:testDataForPartsList forDevice:device]]; - // Make sure that the cluster data in the data storage for endpoints 0 and 1 are present but not for endpoint 2. + // Make sure that the cluster data is removed from the data storage for the endpoint we deleted, but still there for the others. // We do not need to check _persistedClusterData here. _persistedClusterData will be paged in from storage when needed so // just checking data storage should suffice here. dispatch_sync(self->_storageQueue, ^{ - XCTAssertTrue([[controller.controllerDataStore _fetchEndpointIndexForNodeID:deviceID] isEqualToArray:testEndpoints]); + XCTAssertEqualObjects([NSSet setWithArray:[controller.controllerDataStore _fetchEndpointIndexForNodeID:deviceID]], testEndpoints); for (NSNumber * endpoint in testEndpoints) { XCTAssertNotNil(initialClusterIndex); for (NSNumber * cluster in [initialClusterIndex objectForKey:endpoint]) { diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index 05037ef3e16822..b23605ce2eaa4e 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -1626,6 +1626,7 @@ B2E0D7B2245B0B5C003C5B48 /* MTRManualSetupPayloadParser.h in Headers */, 3CF134A7289D8ADA0017A19E /* MTRCSRInfo.h in Headers */, 88E07D612B9A89A4005FD53E /* MTRMetricKeys.h in Headers */, + 3D4733B32BE2D1DA003DC19B /* MTRUtilities.h in Headers */, B2E0D7B1245B0B5C003C5B48 /* Matter.h in Headers */, 7596A84428762729004DAE0E /* MTRDevice.h in Headers */, B2E0D7B8245B0B5C003C5B48 /* MTRSetupPayload.h in Headers */, @@ -1671,7 +1672,6 @@ 514C7A022B64223400DD6D7B /* MTRServerEndpoint_Internal.h in Headers */, 511913FC28C100EF009235E9 /* MTRBaseSubscriptionCallback.h in Headers */, 51565CB12A7AD77600469F18 /* MTRDeviceControllerDataStore.h in Headers */, - 3D4733B32BE2D1DA003DC19B /* MTRUtilities.h in Headers */, 3D843713294977000070D20A /* NSDataSpanConversion.h in Headers */, 991DC08B247704DC00C13860 /* MTRLogging_Internal.h in Headers */, 51FE723F2ACDEF3E00437032 /* MTRCommandPayloadExtensions_Internal.h in Headers */, @@ -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/inet/tests/BUILD.gn b/src/inet/tests/BUILD.gn index 151b08b7c18838..376693a15c205c 100755 --- a/src/inet/tests/BUILD.gn +++ b/src/inet/tests/BUILD.gn @@ -71,6 +71,7 @@ if (chip_build_tests) { ":helpers", "${chip_root}/src/inet", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", ] test_sources = [ "TestBasicPacketFilters.cpp", diff --git a/src/inet/tests/TestBasicPacketFilters.cpp b/src/inet/tests/TestBasicPacketFilters.cpp index 162fe5272d4b94..69494e48f35b78 100644 --- a/src/inet/tests/TestBasicPacketFilters.cpp +++ b/src/inet/tests/TestBasicPacketFilters.cpp @@ -18,11 +18,12 @@ #include #include -#include +#include #include #include #include +#include #include #include #include diff --git a/src/inet/tests/TestInetAddress.cpp b/src/inet/tests/TestInetAddress.cpp index 1b7e7bdfbefd40..900ce2d829b873 100644 --- a/src/inet/tests/TestInetAddress.cpp +++ b/src/inet/tests/TestInetAddress.cpp @@ -26,10 +26,11 @@ #include -#include +#include #include #include +#include #if CHIP_SYSTEM_CONFIG_USE_LWIP #include diff --git a/src/inet/tests/TestInetEndPoint.cpp b/src/inet/tests/TestInetEndPoint.cpp index 3e6f613a4cb179..10209c0ba9b50f 100644 --- a/src/inet/tests/TestInetEndPoint.cpp +++ b/src/inet/tests/TestInetEndPoint.cpp @@ -29,11 +29,12 @@ #include #include -#include +#include #include #include #include +#include #include #include #include diff --git a/src/inet/tests/TestInetErrorStr.cpp b/src/inet/tests/TestInetErrorStr.cpp index 8e92a040d8567b..60f88a6a5e4767 100644 --- a/src/inet/tests/TestInetErrorStr.cpp +++ b/src/inet/tests/TestInetErrorStr.cpp @@ -28,10 +28,11 @@ #include #include -#include +#include #include #include +#include #include using namespace chip; 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/tests/BUILD.gn b/src/lib/address_resolve/tests/BUILD.gn index 994833f21a0020..9521e6f7b27c6d 100644 --- a/src/lib/address_resolve/tests/BUILD.gn +++ b/src/lib/address_resolve/tests/BUILD.gn @@ -28,6 +28,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/address_resolve", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/protocols", ] } diff --git a/src/lib/address_resolve/tests/TestAddressResolve_DefaultImpl.cpp b/src/lib/address_resolve/tests/TestAddressResolve_DefaultImpl.cpp index 74dc3bd81b29d2..266939fa3f5d3b 100644 --- a/src/lib/address_resolve/tests/TestAddressResolve_DefaultImpl.cpp +++ b/src/lib/address_resolve/tests/TestAddressResolve_DefaultImpl.cpp @@ -13,9 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include + +#include #include +#include using namespace chip; using namespace chip::AddressResolve; 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/asn1/tests/BUILD.gn b/src/lib/asn1/tests/BUILD.gn index 83c3ec8d3d9e43..a6b2d1a5a71248 100644 --- a/src/lib/asn1/tests/BUILD.gn +++ b/src/lib/asn1/tests/BUILD.gn @@ -25,6 +25,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/asn1", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/platform", ] diff --git a/src/lib/asn1/tests/TestASN1.cpp b/src/lib/asn1/tests/TestASN1.cpp index db8b1ae8ccf595..6633867895e74a 100644 --- a/src/lib/asn1/tests/TestASN1.cpp +++ b/src/lib/asn1/tests/TestASN1.cpp @@ -24,14 +24,16 @@ * decode interfaces. * */ -#include #include #include #include +#include + #include #include +#include #include using namespace chip; diff --git a/src/lib/core/tests/BUILD.gn b/src/lib/core/tests/BUILD.gn index 94a6ace3636be1..eb17707dec1755 100644 --- a/src/lib/core/tests/BUILD.gn +++ b/src/lib/core/tests/BUILD.gn @@ -43,6 +43,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/core:vectortlv", "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/platform", diff --git a/src/lib/core/tests/TestCATValues.cpp b/src/lib/core/tests/TestCATValues.cpp index a8563905ecb648..6e96610393357f 100644 --- a/src/lib/core/tests/TestCATValues.cpp +++ b/src/lib/core/tests/TestCATValues.cpp @@ -16,9 +16,10 @@ * limitations under the License. */ -#include +#include #include +#include using namespace chip; diff --git a/src/lib/core/tests/TestCHIPCallback.cpp b/src/lib/core/tests/TestCHIPCallback.cpp index 88483dce445bc1..383aef254b140f 100644 --- a/src/lib/core/tests/TestCHIPCallback.cpp +++ b/src/lib/core/tests/TestCHIPCallback.cpp @@ -21,9 +21,11 @@ * This file implements a test for CHIP Callback * */ -#include + +#include #include +#include #include #include diff --git a/src/lib/core/tests/TestCHIPError.cpp b/src/lib/core/tests/TestCHIPError.cpp index ba0c25906623a8..f9dbbd9eb2a710 100644 --- a/src/lib/core/tests/TestCHIPError.cpp +++ b/src/lib/core/tests/TestCHIPError.cpp @@ -18,9 +18,9 @@ #include -#include +#include -#include +#include namespace chip { namespace { diff --git a/src/lib/core/tests/TestCHIPErrorStr.cpp b/src/lib/core/tests/TestCHIPErrorStr.cpp index 295dc895fc52fb..d466eb281fe0fb 100644 --- a/src/lib/core/tests/TestCHIPErrorStr.cpp +++ b/src/lib/core/tests/TestCHIPErrorStr.cpp @@ -28,10 +28,11 @@ #include #include -#include +#include #include #include +#include using namespace chip; diff --git a/src/lib/core/tests/TestGroupedCallbackList.cpp b/src/lib/core/tests/TestGroupedCallbackList.cpp index da09d162ce1d00..f2d85ec13bf168 100644 --- a/src/lib/core/tests/TestGroupedCallbackList.cpp +++ b/src/lib/core/tests/TestGroupedCallbackList.cpp @@ -16,9 +16,10 @@ * limitations under the License. */ -#include +#include #include +#include #include #include diff --git a/src/lib/core/tests/TestOTAImageHeader.cpp b/src/lib/core/tests/TestOTAImageHeader.cpp index 8413dbdce36f0e..bee9da3978bed0 100644 --- a/src/lib/core/tests/TestOTAImageHeader.cpp +++ b/src/lib/core/tests/TestOTAImageHeader.cpp @@ -16,9 +16,10 @@ * limitations under the License. */ -#include +#include -#include +#include +#include using namespace chip; diff --git a/src/lib/core/tests/TestOptional.cpp b/src/lib/core/tests/TestOptional.cpp index 9a0e95f1db8da2..e57657464369bd 100644 --- a/src/lib/core/tests/TestOptional.cpp +++ b/src/lib/core/tests/TestOptional.cpp @@ -28,11 +28,12 @@ #include #include +#include + #include +#include #include -#include - using namespace chip; struct Count diff --git a/src/lib/core/tests/TestReferenceCounted.cpp b/src/lib/core/tests/TestReferenceCounted.cpp index 4f3c3cd4182a3c..fc7d01e537bf61 100644 --- a/src/lib/core/tests/TestReferenceCounted.cpp +++ b/src/lib/core/tests/TestReferenceCounted.cpp @@ -27,9 +27,10 @@ #include #include -#include +#include -#include +#include +#include using namespace chip; diff --git a/src/lib/core/tests/TestTLV.cpp b/src/lib/core/tests/TestTLV.cpp index d7861291a56c73..a12411444385d0 100644 --- a/src/lib/core/tests/TestTLV.cpp +++ b/src/lib/core/tests/TestTLV.cpp @@ -23,21 +23,21 @@ * */ -#include #include +#include + #include +#include #include #include #include #include #include - #include #include #include #include - #include #include diff --git a/src/lib/core/tests/TestTLVVectorWriter.cpp b/src/lib/core/tests/TestTLVVectorWriter.cpp index d2b604fa7e876f..01c2a445a52de9 100644 --- a/src/lib/core/tests/TestTLVVectorWriter.cpp +++ b/src/lib/core/tests/TestTLVVectorWriter.cpp @@ -16,19 +16,19 @@ * limitations under the License. */ -#include - -#include - #include #include #include #include +#include + #include #include +#include #include #include +#include #include #include 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/minimal_mdns/core/tests/BUILD.gn b/src/lib/dnssd/minimal_mdns/core/tests/BUILD.gn index 39b59bb999c9ad..9a84057e18cd66 100644 --- a/src/lib/dnssd/minimal_mdns/core/tests/BUILD.gn +++ b/src/lib/dnssd/minimal_mdns/core/tests/BUILD.gn @@ -41,6 +41,7 @@ chip_test_suite("tests") { public_deps = [ ":support", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/dnssd/minimal_mdns/core", ] } diff --git a/src/lib/dnssd/minimal_mdns/core/tests/TestFlatAllocatedQName.cpp b/src/lib/dnssd/minimal_mdns/core/tests/TestFlatAllocatedQName.cpp index c9ab4f222ef6f0..5ae56f46a8e2a6 100644 --- a/src/lib/dnssd/minimal_mdns/core/tests/TestFlatAllocatedQName.cpp +++ b/src/lib/dnssd/minimal_mdns/core/tests/TestFlatAllocatedQName.cpp @@ -14,8 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include +#include + +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/core/tests/TestHeapQName.cpp b/src/lib/dnssd/minimal_mdns/core/tests/TestHeapQName.cpp index 22287751ac5f05..7857ce4335b1bd 100644 --- a/src/lib/dnssd/minimal_mdns/core/tests/TestHeapQName.cpp +++ b/src/lib/dnssd/minimal_mdns/core/tests/TestHeapQName.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include #include diff --git a/src/lib/dnssd/minimal_mdns/core/tests/TestQName.cpp b/src/lib/dnssd/minimal_mdns/core/tests/TestQName.cpp index 46c0b517162133..26bed1aea129b4 100644 --- a/src/lib/dnssd/minimal_mdns/core/tests/TestQName.cpp +++ b/src/lib/dnssd/minimal_mdns/core/tests/TestQName.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/core/tests/TestRecordWriter.cpp b/src/lib/dnssd/minimal_mdns/core/tests/TestRecordWriter.cpp index f8dbc220978c87..6f0885932bcb1b 100644 --- a/src/lib/dnssd/minimal_mdns/core/tests/TestRecordWriter.cpp +++ b/src/lib/dnssd/minimal_mdns/core/tests/TestRecordWriter.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/records/tests/BUILD.gn b/src/lib/dnssd/minimal_mdns/records/tests/BUILD.gn index 90a73141ff61d0..243da1423a08a2 100644 --- a/src/lib/dnssd/minimal_mdns/records/tests/BUILD.gn +++ b/src/lib/dnssd/minimal_mdns/records/tests/BUILD.gn @@ -32,6 +32,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/dnssd/minimal_mdns/records", ] } diff --git a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecord.cpp b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecord.cpp index 3139635c54a56b..c828d23b2f934b 100644 --- a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecord.cpp +++ b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecord.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordIP.cpp b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordIP.cpp index c79507d2f454e6..bff8a50d9da1d5 100644 --- a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordIP.cpp +++ b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordIP.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordPtr.cpp b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordPtr.cpp index 52cab32b727fd0..adbfd6aba1359b 100644 --- a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordPtr.cpp +++ b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordPtr.cpp @@ -15,8 +15,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordSrv.cpp b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordSrv.cpp index b213f11efd32cc..8bab8b856edac9 100644 --- a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordSrv.cpp +++ b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordSrv.cpp @@ -15,8 +15,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordTxt.cpp b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordTxt.cpp index f77066b8361fdc..f97ba2dc0a0329 100644 --- a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordTxt.cpp +++ b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordTxt.cpp @@ -15,8 +15,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/responders/tests/BUILD.gn b/src/lib/dnssd/minimal_mdns/responders/tests/BUILD.gn index 940cc82698e14a..3c8437c068cc84 100644 --- a/src/lib/dnssd/minimal_mdns/responders/tests/BUILD.gn +++ b/src/lib/dnssd/minimal_mdns/responders/tests/BUILD.gn @@ -30,6 +30,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/dnssd/minimal_mdns", "${chip_root}/src/lib/dnssd/minimal_mdns:default_policy", "${chip_root}/src/lib/dnssd/minimal_mdns/responders", diff --git a/src/lib/dnssd/minimal_mdns/responders/tests/TestIPResponder.cpp b/src/lib/dnssd/minimal_mdns/responders/tests/TestIPResponder.cpp index b24f2bedd4a1a8..691a458c9343d6 100644 --- a/src/lib/dnssd/minimal_mdns/responders/tests/TestIPResponder.cpp +++ b/src/lib/dnssd/minimal_mdns/responders/tests/TestIPResponder.cpp @@ -18,11 +18,12 @@ #include +#include + +#include #include #include -#include - namespace { using namespace chip; diff --git a/src/lib/dnssd/minimal_mdns/responders/tests/TestPtrResponder.cpp b/src/lib/dnssd/minimal_mdns/responders/tests/TestPtrResponder.cpp index f1c2ba6f9e25c2..b10e19a0ad0407 100644 --- a/src/lib/dnssd/minimal_mdns/responders/tests/TestPtrResponder.cpp +++ b/src/lib/dnssd/minimal_mdns/responders/tests/TestPtrResponder.cpp @@ -18,11 +18,12 @@ #include +#include + +#include #include #include -#include - namespace { using namespace chip; diff --git a/src/lib/dnssd/minimal_mdns/responders/tests/TestQueryResponder.cpp b/src/lib/dnssd/minimal_mdns/responders/tests/TestQueryResponder.cpp index bf0ff0413e38f6..80d0029ffa78d4 100644 --- a/src/lib/dnssd/minimal_mdns/responders/tests/TestQueryResponder.cpp +++ b/src/lib/dnssd/minimal_mdns/responders/tests/TestQueryResponder.cpp @@ -18,9 +18,10 @@ #include -#include +#include -#include +#include +#include namespace { diff --git a/src/lib/dnssd/minimal_mdns/tests/BUILD.gn b/src/lib/dnssd/minimal_mdns/tests/BUILD.gn index 17f9868609748c..47e83650d41acc 100644 --- a/src/lib/dnssd/minimal_mdns/tests/BUILD.gn +++ b/src/lib/dnssd/minimal_mdns/tests/BUILD.gn @@ -37,6 +37,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/dnssd", "${chip_root}/src/lib/dnssd/minimal_mdns", "${chip_root}/src/transport/raw/tests:helpers", diff --git a/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h b/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h index 1aabc6738d00e6..fe85abdbf53179 100644 --- a/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h +++ b/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h @@ -22,6 +22,9 @@ #include #include +#include + +#include #include #include #include @@ -31,8 +34,6 @@ #include #include -#include - namespace mdns { namespace Minimal { namespace test { diff --git a/src/lib/dnssd/minimal_mdns/tests/TestAdvertiser.cpp b/src/lib/dnssd/minimal_mdns/tests/TestAdvertiser.cpp index c868939573f1c7..1a66865c143a2e 100644 --- a/src/lib/dnssd/minimal_mdns/tests/TestAdvertiser.cpp +++ b/src/lib/dnssd/minimal_mdns/tests/TestAdvertiser.cpp @@ -20,6 +20,9 @@ #include #include +#include + +#include #include #include #include @@ -33,8 +36,6 @@ #include #include -#include - namespace { using namespace std; diff --git a/src/lib/dnssd/minimal_mdns/tests/TestMinimalMdnsAllocator.cpp b/src/lib/dnssd/minimal_mdns/tests/TestMinimalMdnsAllocator.cpp index f571e81fcf27d1..41577dc4797f1a 100644 --- a/src/lib/dnssd/minimal_mdns/tests/TestMinimalMdnsAllocator.cpp +++ b/src/lib/dnssd/minimal_mdns/tests/TestMinimalMdnsAllocator.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include using namespace chip; diff --git a/src/lib/dnssd/minimal_mdns/tests/TestQueryReplyFilter.cpp b/src/lib/dnssd/minimal_mdns/tests/TestQueryReplyFilter.cpp index 234b6876c6b7fe..769bcfaa8f8eae 100644 --- a/src/lib/dnssd/minimal_mdns/tests/TestQueryReplyFilter.cpp +++ b/src/lib/dnssd/minimal_mdns/tests/TestQueryReplyFilter.cpp @@ -14,8 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include +#include + +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/tests/TestRecordData.cpp b/src/lib/dnssd/minimal_mdns/tests/TestRecordData.cpp index 295ed2296215bf..dcd48959be01ea 100644 --- a/src/lib/dnssd/minimal_mdns/tests/TestRecordData.cpp +++ b/src/lib/dnssd/minimal_mdns/tests/TestRecordData.cpp @@ -14,12 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include #include #include -#include +#include + +#include namespace { diff --git a/src/lib/dnssd/minimal_mdns/tests/TestResponseSender.cpp b/src/lib/dnssd/minimal_mdns/tests/TestResponseSender.cpp index e248a647bf2f6d..abfceb52080f13 100644 --- a/src/lib/dnssd/minimal_mdns/tests/TestResponseSender.cpp +++ b/src/lib/dnssd/minimal_mdns/tests/TestResponseSender.cpp @@ -14,13 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include #include #include -#include +#include +#include #include #include #include @@ -28,7 +30,6 @@ #include #include #include - #include namespace { diff --git a/src/lib/dnssd/platform/tests/BUILD.gn b/src/lib/dnssd/platform/tests/BUILD.gn index 966923eebae998..b28ba928c6e827 100644 --- a/src/lib/dnssd/platform/tests/BUILD.gn +++ b/src/lib/dnssd/platform/tests/BUILD.gn @@ -22,6 +22,9 @@ chip_test_suite("tests") { if (chip_device_platform == "fake") { test_sources = [ "TestPlatform.cpp" ] - public_deps = [ "${chip_root}/src/lib/dnssd" ] + public_deps = [ + "${chip_root}/src/lib/core:string-builder-adapters", + "${chip_root}/src/lib/dnssd", + ] } } diff --git a/src/lib/dnssd/platform/tests/TestPlatform.cpp b/src/lib/dnssd/platform/tests/TestPlatform.cpp index 324863a948902d..5494bbcc3d402c 100644 --- a/src/lib/dnssd/platform/tests/TestPlatform.cpp +++ b/src/lib/dnssd/platform/tests/TestPlatform.cpp @@ -16,15 +16,15 @@ * limitations under the License. */ +#include + #include +#include #include - #include #include #include -#include - #if CHIP_DEVICE_LAYER_TARGET_FAKE != 1 #error "This test is designed for use only with the fake platform" #endif diff --git a/src/lib/dnssd/tests/BUILD.gn b/src/lib/dnssd/tests/BUILD.gn index cdcb4bab0e27a1..e8ab101ae8e09f 100644 --- a/src/lib/dnssd/tests/BUILD.gn +++ b/src/lib/dnssd/tests/BUILD.gn @@ -25,7 +25,10 @@ chip_test_suite("tests") { "TestTxtFields.cpp", ] - public_deps = [ "${chip_root}/src/lib/dnssd" ] + public_deps = [ + "${chip_root}/src/lib/core:string-builder-adapters", + "${chip_root}/src/lib/dnssd", + ] if (chip_mdns == "minimal") { test_sources += [ diff --git a/src/lib/dnssd/tests/TestActiveResolveAttempts.cpp b/src/lib/dnssd/tests/TestActiveResolveAttempts.cpp index 6d778808f3e669..308cede6957103 100644 --- a/src/lib/dnssd/tests/TestActiveResolveAttempts.cpp +++ b/src/lib/dnssd/tests/TestActiveResolveAttempts.cpp @@ -14,9 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include +#include + +#include +#include namespace { diff --git a/src/lib/dnssd/tests/TestIncrementalResolve.cpp b/src/lib/dnssd/tests/TestIncrementalResolve.cpp index 053d0dd96856ee..930b837fbbfbbb 100644 --- a/src/lib/dnssd/tests/TestIncrementalResolve.cpp +++ b/src/lib/dnssd/tests/TestIncrementalResolve.cpp @@ -20,6 +20,9 @@ #include +#include + +#include #include #include #include @@ -29,8 +32,6 @@ #include #include -#include - using namespace chip; using namespace chip::Dnssd; using namespace mdns::Minimal; @@ -308,7 +309,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 +398,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/TestServiceNaming.cpp b/src/lib/dnssd/tests/TestServiceNaming.cpp index 0fa26723dab779..485595ab7d8410 100644 --- a/src/lib/dnssd/tests/TestServiceNaming.cpp +++ b/src/lib/dnssd/tests/TestServiceNaming.cpp @@ -20,7 +20,9 @@ #include -#include +#include + +#include using namespace chip; using namespace chip::Dnssd; diff --git a/src/lib/dnssd/tests/TestTxtFields.cpp b/src/lib/dnssd/tests/TestTxtFields.cpp index b80f1c0682ef32..3de62f235be98b 100644 --- a/src/lib/dnssd/tests/TestTxtFields.cpp +++ b/src/lib/dnssd/tests/TestTxtFields.cpp @@ -22,9 +22,10 @@ #include #include -#include +#include -#include +#include +#include using namespace chip; using namespace chip::Dnssd; @@ -306,7 +307,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 +414,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 +646,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().supportsTcpClient); + EXPECT_FALSE(nodeData.Get().supportsTcpServer); + + // Supporting TCP Server only + strcpy(key, "T"); + strcpy(val, "4"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); - EXPECT_TRUE(nodeData.Get().supportsTcp == false); + EXPECT_FALSE(nodeData.Get().supportsTcpClient); + EXPECT_TRUE(nodeData.Get().supportsTcpServer); - // Invalid value, stil false + // 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 +1034,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_FALSE(nodeData.resolutionData.supportsTcpServer); + EXPECT_TRUE(nodeData.resolutionData.supportsTcpClient); + + // 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_EQ(nodeData.resolutionData.supportsTcp, false); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpClient); + EXPECT_FALSE(nodeData.resolutionData.supportsTcpServer); - // Invalid value, stil false + // 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/format/tests/BUILD.gn b/src/lib/format/tests/BUILD.gn index 1001a3bd9e77d4..840a2eede60c78 100644 --- a/src/lib/format/tests/BUILD.gn +++ b/src/lib/format/tests/BUILD.gn @@ -36,6 +36,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/controller/data_model:cluster-tlv-metadata", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/format:flat-tree", "${chip_root}/src/lib/format:protocol-decoder", "${chip_root}/src/lib/format:protocol-tlv-metadata", diff --git a/src/lib/format/tests/TestDecoding.cpp b/src/lib/format/tests/TestDecoding.cpp index ae5c2efc553fb6..2fc7cf8f59fd6c 100644 --- a/src/lib/format/tests/TestDecoding.cpp +++ b/src/lib/format/tests/TestDecoding.cpp @@ -14,15 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include + +#include #include #include #include - #include #include -#include - #include "sample_data.h" namespace { diff --git a/src/lib/format/tests/TestFlatTree.cpp b/src/lib/format/tests/TestFlatTree.cpp index fcf8e2713bf6b5..05f401b7d8232d 100644 --- a/src/lib/format/tests/TestFlatTree.cpp +++ b/src/lib/format/tests/TestFlatTree.cpp @@ -14,15 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include - -#include #include - #include -#include +#include + +#include +#include +#include namespace { diff --git a/src/lib/format/tests/TestFlatTreePosition.cpp b/src/lib/format/tests/TestFlatTreePosition.cpp index cf5a26e6c8662f..b578f68583cbd2 100644 --- a/src/lib/format/tests/TestFlatTreePosition.cpp +++ b/src/lib/format/tests/TestFlatTreePosition.cpp @@ -14,17 +14,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include - -#include #include #include #include -#include +#include + +#include +#include +#include +#include namespace { 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/shell/tests/BUILD.gn b/src/lib/shell/tests/BUILD.gn index 0b5f7d5fd43222..9b71114424d8de 100644 --- a/src/lib/shell/tests/BUILD.gn +++ b/src/lib/shell/tests/BUILD.gn @@ -29,6 +29,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/shell", ] } diff --git a/src/lib/shell/tests/TestShellStreamerStdio.cpp b/src/lib/shell/tests/TestShellStreamerStdio.cpp index dde770c950183c..b71ebaf80ae50d 100644 --- a/src/lib/shell/tests/TestShellStreamerStdio.cpp +++ b/src/lib/shell/tests/TestShellStreamerStdio.cpp @@ -15,8 +15,9 @@ * limitations under the License. */ -#include +#include +#include #include #include diff --git a/src/lib/shell/tests/TestShellTokenizeLine.cpp b/src/lib/shell/tests/TestShellTokenizeLine.cpp index 8ed6c0eecde779..64bb301dc52141 100644 --- a/src/lib/shell/tests/TestShellTokenizeLine.cpp +++ b/src/lib/shell/tests/TestShellTokenizeLine.cpp @@ -15,8 +15,9 @@ * limitations under the License. */ -#include +#include +#include #include // Include entire C++ file to have access to functions-under-test 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 -#include - #include +#include + +#include +#include + namespace chip { namespace Thread { @@ -70,7 +72,7 @@ class ThreadTLV final mLength = aLength; } - const void * GetValue() const + const uint8_t * GetValue() const { assert(mLength != kLengthEscape); @@ -79,75 +81,44 @@ class ThreadTLV final return reinterpret_cast(this) + sizeof(*this); } - void * GetValue() { return const_cast(const_cast(this)->GetValue()); } + uint8_t * GetValue() { return const_cast(const_cast(this)->GetValue()); } + + ByteSpan GetValueAsSpan() const { return ByteSpan(static_cast(GetValue()), GetLength()); } void Get64(uint64_t & aValue) const { assert(GetLength() >= sizeof(aValue)); - - const uint8_t * p = reinterpret_cast(GetValue()); - aValue = // - (static_cast(p[0]) << 56) | // - (static_cast(p[1]) << 48) | // - (static_cast(p[2]) << 40) | // - (static_cast(p[3]) << 32) | // - (static_cast(p[4]) << 24) | // - (static_cast(p[5]) << 16) | // - (static_cast(p[6]) << 8) | // - (static_cast(p[7])); + aValue = Encoding::BigEndian::Get64(GetValue()); } - void Get16(uint16_t & aValue) const + void Get32(uint32_t & aValue) const { assert(GetLength() >= sizeof(aValue)); - - const uint8_t * p = static_cast(GetValue()); - - aValue = static_cast(p[0] << 8 | p[1]); + aValue = Encoding::BigEndian::Get32(GetValue()); } - void Get8(uint8_t & aValue) const + void Get16(uint16_t & aValue) const { assert(GetLength() >= sizeof(aValue)); - aValue = *static_cast(GetValue()); + aValue = Encoding::BigEndian::Get16(GetValue()); } void Set64(uint64_t aValue) { - uint8_t * value = static_cast(GetValue()); - SetLength(sizeof(aValue)); - - value[0] = static_cast((aValue >> 56) & 0xff); - value[1] = static_cast((aValue >> 48) & 0xff); - value[2] = static_cast((aValue >> 40) & 0xff); - value[3] = static_cast((aValue >> 32) & 0xff); - value[4] = static_cast((aValue >> 24) & 0xff); - value[5] = static_cast((aValue >> 16) & 0xff); - value[6] = static_cast((aValue >> 8) & 0xff); - value[7] = static_cast(aValue & 0xff); + Encoding::BigEndian::Put64(GetValue(), aValue); } - void Set16(uint16_t aValue) + void Set32(uint32_t aValue) { - uint8_t * value = static_cast(GetValue()); - SetLength(sizeof(aValue)); - - value[0] = static_cast(aValue >> 8); - value[1] = static_cast(aValue & 0xff); - } - - void Set8(uint8_t aValue) - { - SetLength(sizeof(aValue)); - *static_cast(GetValue()) = aValue; + Encoding::BigEndian::Put32(GetValue(), aValue); } - void Set8(int8_t aValue) + void Set16(uint16_t aValue) { SetLength(sizeof(aValue)); - *static_cast(GetValue()) = aValue; + Encoding::BigEndian::Put16(GetValue(), aValue); } void SetValue(const void * aValue, uint8_t aLength) @@ -218,24 +189,16 @@ CHIP_ERROR OperationalDataset::Init(ByteSpan aData) CHIP_ERROR OperationalDataset::GetActiveTimestamp(uint64_t & aActiveTimestamp) const { const ThreadTLV * tlv = Locate(ThreadTLV::kActiveTimestamp); - - if (tlv != nullptr) - { - tlv->Get64(aActiveTimestamp); - return CHIP_NO_ERROR; - } - - return CHIP_ERROR_TLV_TAG_NOT_FOUND; + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() == sizeof(aActiveTimestamp), CHIP_ERROR_INVALID_TLV_ELEMENT); + tlv->Get64(aActiveTimestamp); + return CHIP_NO_ERROR; } CHIP_ERROR OperationalDataset::SetActiveTimestamp(uint64_t aActiveTimestamp) { ThreadTLV * tlv = MakeRoom(ThreadTLV::kActiveTimestamp, sizeof(*tlv) + sizeof(aActiveTimestamp)); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->Set64(aActiveTimestamp); @@ -247,26 +210,19 @@ CHIP_ERROR OperationalDataset::SetActiveTimestamp(uint64_t aActiveTimestamp) CHIP_ERROR OperationalDataset::GetChannel(uint16_t & aChannel) const { const ThreadTLV * tlv = Locate(ThreadTLV::kChannel); - - if (tlv != nullptr) - { - const uint8_t * value = reinterpret_cast(tlv->GetValue()); - aChannel = static_cast((value[1] << 8) | value[2]); - return CHIP_NO_ERROR; - } - - return CHIP_ERROR_TLV_TAG_NOT_FOUND; + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() == 3, CHIP_ERROR_INVALID_TLV_ELEMENT); + // Note: The channel page (byte 0) is not returned + const uint8_t * value = tlv->GetValue(); + aChannel = static_cast((value[1] << 8) | value[2]); + return CHIP_NO_ERROR; } CHIP_ERROR OperationalDataset::SetChannel(uint16_t aChannel) { uint8_t value[] = { 0, static_cast(aChannel >> 8), static_cast(aChannel & 0xff) }; ThreadTLV * tlv = MakeRoom(ThreadTLV::kChannel, sizeof(*tlv) + sizeof(value)); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->SetValue(value, sizeof(value)); @@ -278,13 +234,7 @@ CHIP_ERROR OperationalDataset::SetChannel(uint16_t aChannel) CHIP_ERROR OperationalDataset::GetExtendedPanId(uint8_t (&aExtendedPanId)[kSizeExtendedPanId]) const { ByteSpan extPanIdSpan; - CHIP_ERROR error = GetExtendedPanIdAsByteSpan(extPanIdSpan); - - if (error != CHIP_NO_ERROR) - { - return error; - } - + ReturnErrorOnFailure(GetExtendedPanIdAsByteSpan(extPanIdSpan)); memcpy(aExtendedPanId, extPanIdSpan.data(), extPanIdSpan.size()); return CHIP_NO_ERROR; } @@ -292,17 +242,8 @@ CHIP_ERROR OperationalDataset::GetExtendedPanId(uint8_t (&aExtendedPanId)[kSizeE CHIP_ERROR OperationalDataset::GetExtendedPanIdAsByteSpan(ByteSpan & span) const { const ThreadTLV * tlv = Locate(ThreadTLV::kExtendedPanId); - - if (tlv == nullptr) - { - return CHIP_ERROR_TLV_TAG_NOT_FOUND; - } - - if (tlv->GetLength() != kSizeExtendedPanId) - { - return CHIP_ERROR_INVALID_TLV_ELEMENT; - } - + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() == kSizeExtendedPanId, CHIP_ERROR_INVALID_TLV_ELEMENT); span = ByteSpan(static_cast(tlv->GetValue()), tlv->GetLength()); return CHIP_NO_ERROR; } @@ -310,11 +251,7 @@ CHIP_ERROR OperationalDataset::GetExtendedPanIdAsByteSpan(ByteSpan & span) const CHIP_ERROR OperationalDataset::SetExtendedPanId(const uint8_t (&aExtendedPanId)[kSizeExtendedPanId]) { ThreadTLV * tlv = MakeRoom(ThreadTLV::kExtendedPanId, sizeof(*tlv) + sizeof(aExtendedPanId)); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->SetValue(aExtendedPanId, sizeof(aExtendedPanId)); @@ -328,24 +265,16 @@ CHIP_ERROR OperationalDataset::SetExtendedPanId(const uint8_t (&aExtendedPanId)[ CHIP_ERROR OperationalDataset::GetMasterKey(uint8_t (&aMasterKey)[kSizeMasterKey]) const { const ThreadTLV * tlv = Locate(ThreadTLV::kMasterKey); - - if (tlv != nullptr) - { - memcpy(aMasterKey, tlv->GetValue(), sizeof(aMasterKey)); - return CHIP_NO_ERROR; - } - - return CHIP_ERROR_TLV_TAG_NOT_FOUND; + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() == sizeof(aMasterKey), CHIP_ERROR_INVALID_TLV_ELEMENT); + memcpy(aMasterKey, tlv->GetValue(), sizeof(aMasterKey)); + return CHIP_NO_ERROR; } CHIP_ERROR OperationalDataset::SetMasterKey(const uint8_t (&aMasterKey)[kSizeMasterKey]) { ThreadTLV * tlv = MakeRoom(ThreadTLV::kMasterKey, sizeof(*tlv) + sizeof(aMasterKey)); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->SetValue(aMasterKey, sizeof(aMasterKey)); @@ -359,24 +288,16 @@ CHIP_ERROR OperationalDataset::SetMasterKey(const uint8_t (&aMasterKey)[kSizeMas CHIP_ERROR OperationalDataset::GetMeshLocalPrefix(uint8_t (&aMeshLocalPrefix)[kSizeMeshLocalPrefix]) const { const ThreadTLV * tlv = Locate(ThreadTLV::kMeshLocalPrefix); - - if (tlv != nullptr) - { - memcpy(aMeshLocalPrefix, tlv->GetValue(), sizeof(aMeshLocalPrefix)); - return CHIP_NO_ERROR; - } - - return CHIP_ERROR_TLV_TAG_NOT_FOUND; + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() == sizeof(aMeshLocalPrefix), CHIP_ERROR_INVALID_TLV_ELEMENT); + memcpy(aMeshLocalPrefix, tlv->GetValue(), sizeof(aMeshLocalPrefix)); + return CHIP_NO_ERROR; } CHIP_ERROR OperationalDataset::SetMeshLocalPrefix(const uint8_t (&aMeshLocalPrefix)[kSizeMeshLocalPrefix]) { ThreadTLV * tlv = MakeRoom(ThreadTLV::kMeshLocalPrefix, sizeof(*tlv) + sizeof(aMeshLocalPrefix)); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->SetValue(aMeshLocalPrefix, sizeof(aMeshLocalPrefix)); @@ -388,32 +309,21 @@ CHIP_ERROR OperationalDataset::SetMeshLocalPrefix(const uint8_t (&aMeshLocalPref CHIP_ERROR OperationalDataset::GetNetworkName(char (&aNetworkName)[kSizeNetworkName + 1]) const { const ThreadTLV * tlv = Locate(ThreadTLV::kNetworkName); - - if (tlv != nullptr) - { - memcpy(aNetworkName, tlv->GetValue(), tlv->GetLength()); - aNetworkName[tlv->GetLength()] = '\0'; - return CHIP_NO_ERROR; - } - - return CHIP_ERROR_TLV_TAG_NOT_FOUND; + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() <= kSizeNetworkName, CHIP_ERROR_INVALID_TLV_ELEMENT); + memcpy(aNetworkName, tlv->GetValue(), tlv->GetLength()); + aNetworkName[tlv->GetLength()] = '\0'; + return CHIP_NO_ERROR; } CHIP_ERROR OperationalDataset::SetNetworkName(const char * aNetworkName) { + VerifyOrReturnError(aNetworkName != nullptr, CHIP_ERROR_INVALID_ARGUMENT); size_t len = strlen(aNetworkName); + VerifyOrReturnError(0 < len && len <= kSizeNetworkName, CHIP_ERROR_INVALID_STRING_LENGTH); - if (len > kSizeNetworkName || len == 0) - { - return CHIP_ERROR_INVALID_STRING_LENGTH; - } - - ThreadTLV * tlv = MakeRoom(ThreadTLV::kNetworkName, static_cast(sizeof(*tlv) + static_cast(len))); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + ThreadTLV * tlv = MakeRoom(ThreadTLV::kNetworkName, sizeof(*tlv) + len); + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->SetValue(aNetworkName, static_cast(len)); @@ -425,24 +335,16 @@ CHIP_ERROR OperationalDataset::SetNetworkName(const char * aNetworkName) CHIP_ERROR OperationalDataset::GetPanId(uint16_t & aPanId) const { const ThreadTLV * tlv = Locate(ThreadTLV::kPanId); - - if (tlv != nullptr) - { - tlv->Get16(aPanId); - return CHIP_NO_ERROR; - } - - return CHIP_ERROR_TLV_TAG_NOT_FOUND; + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() == sizeof(aPanId), CHIP_ERROR_INVALID_TLV_ELEMENT); + tlv->Get16(aPanId); + return CHIP_NO_ERROR; } CHIP_ERROR OperationalDataset::SetPanId(uint16_t aPanId) { ThreadTLV * tlv = MakeRoom(ThreadTLV::kPanId, sizeof(*tlv) + sizeof(aPanId)); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->Set16(aPanId); @@ -454,24 +356,16 @@ CHIP_ERROR OperationalDataset::SetPanId(uint16_t aPanId) CHIP_ERROR OperationalDataset::GetPSKc(uint8_t (&aPSKc)[kSizePSKc]) const { const ThreadTLV * tlv = Locate(ThreadTLV::kPSKc); - - if (tlv != nullptr) - { - memcpy(aPSKc, tlv->GetValue(), sizeof(aPSKc)); - return CHIP_NO_ERROR; - } - - return CHIP_ERROR_TLV_TAG_NOT_FOUND; + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() == sizeof(aPSKc), CHIP_ERROR_INVALID_TLV_ELEMENT); + memcpy(aPSKc, tlv->GetValue(), sizeof(aPSKc)); + return CHIP_NO_ERROR; } CHIP_ERROR OperationalDataset::SetPSKc(const uint8_t (&aPSKc)[kSizePSKc]) { ThreadTLV * tlv = MakeRoom(ThreadTLV::kPSKc, sizeof(*tlv) + sizeof(aPSKc)); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->SetValue(aPSKc, sizeof(aPSKc)); @@ -533,7 +427,7 @@ void OperationalDataset::Remove(uint8_t aType) } } -ThreadTLV * OperationalDataset::MakeRoom(uint8_t aType, uint8_t aSize) +ThreadTLV * OperationalDataset::MakeRoom(uint8_t aType, size_t aSize) { ThreadTLV * tlv = Locate(aType); diff --git a/src/lib/support/ThreadOperationalDataset.h b/src/lib/support/ThreadOperationalDataset.h index e4de3ddaa8d2c5..7bb528d691c193 100644 --- a/src/lib/support/ThreadOperationalDataset.h +++ b/src/lib/support/ThreadOperationalDataset.h @@ -54,7 +54,6 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully initialized the dataset. * @retval CHIP_ERROR_INVALID_ARGUMENT The dataset length @p aLength is too long or @p data is corrupted. - * */ CHIP_ERROR Init(ByteSpan aData); @@ -65,7 +64,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the active timestamp. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread active timestamp is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetActiveTimestamp(uint64_t & aActiveTimestamp) const; @@ -76,7 +75,6 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the active timestamp. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread active timestamp. - * */ CHIP_ERROR SetActiveTimestamp(uint64_t aActiveTimestamp); @@ -87,7 +85,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the channel. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread channel is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetChannel(uint16_t & aChannel) const; @@ -98,7 +96,6 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the channel. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread channel. - * */ CHIP_ERROR SetChannel(uint16_t aChannel); @@ -109,7 +106,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the extended PAN ID. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread extended PAN ID is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetExtendedPanId(uint8_t (&aExtendedPanId)[kSizeExtendedPanId]) const; @@ -121,7 +118,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the extended PAN ID. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread extended PAN ID is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetExtendedPanIdAsByteSpan(ByteSpan & span) const; @@ -132,7 +129,6 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the extended PAN ID. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread extended PAN ID. - * */ CHIP_ERROR SetExtendedPanId(const uint8_t (&aExtendedPanId)[kSizeExtendedPanId]); @@ -143,7 +139,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the master key. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread master key is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetMasterKey(uint8_t (&aMasterKey)[kSizeMasterKey]) const; @@ -154,13 +150,11 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the master key. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread master key. - * */ CHIP_ERROR SetMasterKey(const uint8_t (&aMasterKey)[kSizeMasterKey]); /** * This method unsets Thread master key to the dataset. - * */ void UnsetMasterKey(void); @@ -171,7 +165,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the mesh local prefix. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread mesh local prefix is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetMeshLocalPrefix(uint8_t (&aMeshLocalPrefix)[kSizeMeshLocalPrefix]) const; @@ -182,7 +176,6 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the Thread mesh local prefix. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread mesh local prefix. - * */ CHIP_ERROR SetMeshLocalPrefix(const uint8_t (&aMeshLocalPrefix)[kSizeMeshLocalPrefix]); @@ -193,7 +186,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the network name. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread network name is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetNetworkName(char (&aNetworkName)[kSizeNetworkName + 1]) const; @@ -204,7 +197,6 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the network name. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread network name. - * */ CHIP_ERROR SetNetworkName(const char * aNetworkName); @@ -215,7 +207,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the PAN ID. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread PAN ID is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetPanId(uint16_t & aPanId) const; @@ -226,7 +218,6 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the PAN ID. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread PAN ID. - * */ CHIP_ERROR SetPanId(uint16_t aPanId); @@ -237,7 +228,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the PSKc. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread PSKc is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetPSKc(uint8_t (&aPSKc)[kSizePSKc]) const; @@ -248,13 +239,11 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the PSKc. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread PSKc. - * */ CHIP_ERROR SetPSKc(const uint8_t (&aPSKc)[kSizePSKc]); /** * This method unsets Thread PSKc to the dataset. - * */ void UnsetPSKc(void); @@ -296,12 +285,12 @@ class OperationalDataset ThreadTLV & End(void) { return const_cast(const_cast(this)->End()); } void Remove(uint8_t aType); void Remove(ThreadTLV & aTlv); - ThreadTLV * MakeRoom(uint8_t aType, uint8_t aSize); + ThreadTLV * MakeRoom(uint8_t aType, size_t aSize); bool Has(uint8_t aType) const { return Locate(aType) != nullptr; } uint8_t mData[kSizeOperationalDataset]; - uint8_t mLength; + uint8_t mLength = 0; }; } // namespace Thread -}; // namespace chip +} // namespace chip diff --git a/src/lib/support/tests/BUILD.gn b/src/lib/support/tests/BUILD.gn index 659ba00d0395ff..c6bfddb9269a7a 100644 --- a/src/lib/support/tests/BUILD.gn +++ b/src/lib/support/tests/BUILD.gn @@ -88,6 +88,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/credentials", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support:static-support", "${chip_root}/src/lib/support:testing", "${chip_root}/src/lib/support/jsontlv", diff --git a/src/lib/support/tests/TestBitMask.cpp b/src/lib/support/tests/TestBitMask.cpp index f19c90fb2e20af..7d7798a4fa85ee 100644 --- a/src/lib/support/tests/TestBitMask.cpp +++ b/src/lib/support/tests/TestBitMask.cpp @@ -14,13 +14,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include + #include #include #include #include +#include + +#include + using namespace chip; namespace { diff --git a/src/lib/support/tests/TestBufferReader.cpp b/src/lib/support/tests/TestBufferReader.cpp index 6d14c3973f58ed..97db9cf09737b9 100644 --- a/src/lib/support/tests/TestBufferReader.cpp +++ b/src/lib/support/tests/TestBufferReader.cpp @@ -22,11 +22,13 @@ * */ -#include -#include - #include +#include + +#include +#include + using namespace chip; using namespace chip::Encoding::LittleEndian; diff --git a/src/lib/support/tests/TestBufferWriter.cpp b/src/lib/support/tests/TestBufferWriter.cpp index e5d8951d4cf152..1be61f35ad206d 100644 --- a/src/lib/support/tests/TestBufferWriter.cpp +++ b/src/lib/support/tests/TestBufferWriter.cpp @@ -14,9 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include +#include + +#include +#include namespace { diff --git a/src/lib/support/tests/TestBytesCircularBuffer.cpp b/src/lib/support/tests/TestBytesCircularBuffer.cpp index 90305e0cf8590a..4ee192b652649e 100644 --- a/src/lib/support/tests/TestBytesCircularBuffer.cpp +++ b/src/lib/support/tests/TestBytesCircularBuffer.cpp @@ -23,8 +23,9 @@ #include #include -#include +#include +#include #include namespace { diff --git a/src/lib/support/tests/TestBytesToHex.cpp b/src/lib/support/tests/TestBytesToHex.cpp index 1e304811b5e42b..7384958befd415 100644 --- a/src/lib/support/tests/TestBytesToHex.cpp +++ b/src/lib/support/tests/TestBytesToHex.cpp @@ -20,13 +20,15 @@ #include #include -#include +#include +#include #include #include #include #include #include + namespace { using namespace chip; diff --git a/src/lib/support/tests/TestCHIPArgParser.cpp b/src/lib/support/tests/TestCHIPArgParser.cpp index 426758aff1e5c8..f7bcc84fbaf3d6 100644 --- a/src/lib/support/tests/TestCHIPArgParser.cpp +++ b/src/lib/support/tests/TestCHIPArgParser.cpp @@ -22,9 +22,10 @@ #include #include -#include +#include #include +#include #include #include #include diff --git a/src/lib/support/tests/TestCHIPCounter.cpp b/src/lib/support/tests/TestCHIPCounter.cpp index b2c5e21b5038c2..f84ce7e50e0c18 100644 --- a/src/lib/support/tests/TestCHIPCounter.cpp +++ b/src/lib/support/tests/TestCHIPCounter.cpp @@ -18,8 +18,9 @@ #include -#include +#include +#include #include using namespace chip; diff --git a/src/lib/support/tests/TestCHIPMem.cpp b/src/lib/support/tests/TestCHIPMem.cpp index c19d356abfeceb..6f4aa8aa6bcfdb 100644 --- a/src/lib/support/tests/TestCHIPMem.cpp +++ b/src/lib/support/tests/TestCHIPMem.cpp @@ -29,8 +29,9 @@ #include #include -#include +#include +#include #include #include diff --git a/src/lib/support/tests/TestCHIPMemString.cpp b/src/lib/support/tests/TestCHIPMemString.cpp index 10101bd193c0f6..11409d18dc6f69 100644 --- a/src/lib/support/tests/TestCHIPMemString.cpp +++ b/src/lib/support/tests/TestCHIPMemString.cpp @@ -22,8 +22,9 @@ #include #include -#include +#include +#include #include #include #include diff --git a/src/lib/support/tests/TestDefer.cpp b/src/lib/support/tests/TestDefer.cpp index 9b5159bf557830..d0b65fe9cb10c5 100644 --- a/src/lib/support/tests/TestDefer.cpp +++ b/src/lib/support/tests/TestDefer.cpp @@ -20,7 +20,9 @@ #include -#include +#include + +#include namespace { diff --git a/src/lib/support/tests/TestErrorStr.cpp b/src/lib/support/tests/TestErrorStr.cpp index 49ae9f5a9b40ac..809d69b302af0b 100644 --- a/src/lib/support/tests/TestErrorStr.cpp +++ b/src/lib/support/tests/TestErrorStr.cpp @@ -19,10 +19,11 @@ #include #include -#include +#include #include #include +#include using namespace chip; diff --git a/src/lib/support/tests/TestFixedBufferAllocator.cpp b/src/lib/support/tests/TestFixedBufferAllocator.cpp index c5c588041ef65c..a2e30ba7464d3b 100644 --- a/src/lib/support/tests/TestFixedBufferAllocator.cpp +++ b/src/lib/support/tests/TestFixedBufferAllocator.cpp @@ -19,7 +19,10 @@ #include #include -#include + +#include + +#include using namespace chip; diff --git a/src/lib/support/tests/TestFold.cpp b/src/lib/support/tests/TestFold.cpp index 48dbb454dfac3b..b8b1b813c191d0 100644 --- a/src/lib/support/tests/TestFold.cpp +++ b/src/lib/support/tests/TestFold.cpp @@ -16,12 +16,15 @@ * limitations under the License. */ -#include -#include - #include #include #include + +#include + +#include +#include + using namespace chip; namespace { diff --git a/src/lib/support/tests/TestIniEscaping.cpp b/src/lib/support/tests/TestIniEscaping.cpp index 90570add67b18d..61c7db20130150 100644 --- a/src/lib/support/tests/TestIniEscaping.cpp +++ b/src/lib/support/tests/TestIniEscaping.cpp @@ -16,10 +16,13 @@ * limitations under the License. */ -#include -#include #include +#include + +#include +#include + using namespace chip; using namespace chip::IniEscaping; diff --git a/src/lib/support/tests/TestIntrusiveList.cpp b/src/lib/support/tests/TestIntrusiveList.cpp index 50ace6a561e699..6e89b3e344c11e 100644 --- a/src/lib/support/tests/TestIntrusiveList.cpp +++ b/src/lib/support/tests/TestIntrusiveList.cpp @@ -18,8 +18,9 @@ #include #include -#include +#include +#include #include namespace { diff --git a/src/lib/support/tests/TestJsonToTlv.cpp b/src/lib/support/tests/TestJsonToTlv.cpp index 9bc8696fd88621..6499e1dfa573aa 100644 --- a/src/lib/support/tests/TestJsonToTlv.cpp +++ b/src/lib/support/tests/TestJsonToTlv.cpp @@ -17,16 +17,18 @@ #include -#include +#include #include #include #include +#include #include #include #include #include #include + namespace { using namespace chip::Encoding; diff --git a/src/lib/support/tests/TestJsonToTlvToJson.cpp b/src/lib/support/tests/TestJsonToTlvToJson.cpp index 665df4dcb30cab..3321ed8f9ee2e2 100644 --- a/src/lib/support/tests/TestJsonToTlvToJson.cpp +++ b/src/lib/support/tests/TestJsonToTlvToJson.cpp @@ -18,11 +18,12 @@ #include #include -#include +#include #include #include #include +#include #include #include #include diff --git a/src/lib/support/tests/TestPersistedCounter.cpp b/src/lib/support/tests/TestPersistedCounter.cpp index 3d9b13583e49a0..a743369537ae91 100644 --- a/src/lib/support/tests/TestPersistedCounter.cpp +++ b/src/lib/support/tests/TestPersistedCounter.cpp @@ -23,8 +23,10 @@ * */ -#include +#include + #include +#include #include #include #include diff --git a/src/lib/support/tests/TestPool.cpp b/src/lib/support/tests/TestPool.cpp index da76d7ebb70d7b..84eea0c3e3bef7 100644 --- a/src/lib/support/tests/TestPool.cpp +++ b/src/lib/support/tests/TestPool.cpp @@ -25,11 +25,13 @@ #include -#include +#include +#include #include #include #include + namespace chip { template diff --git a/src/lib/support/tests/TestPrivateHeap.cpp b/src/lib/support/tests/TestPrivateHeap.cpp index f808c16cb8e5f6..2a68bb9c925021 100644 --- a/src/lib/support/tests/TestPrivateHeap.cpp +++ b/src/lib/support/tests/TestPrivateHeap.cpp @@ -18,8 +18,9 @@ #include -#include +#include +#include #include namespace { diff --git a/src/lib/support/tests/TestSafeInt.cpp b/src/lib/support/tests/TestSafeInt.cpp index 1464c0e9735b8c..298b23071e5709 100644 --- a/src/lib/support/tests/TestSafeInt.cpp +++ b/src/lib/support/tests/TestSafeInt.cpp @@ -22,7 +22,9 @@ * */ -#include +#include + +#include #include using namespace chip; diff --git a/src/lib/support/tests/TestSafeString.cpp b/src/lib/support/tests/TestSafeString.cpp index 09e7d89e4054f7..6fe71cb5df723a 100644 --- a/src/lib/support/tests/TestSafeString.cpp +++ b/src/lib/support/tests/TestSafeString.cpp @@ -22,8 +22,9 @@ * */ -#include +#include +#include #include using namespace chip; diff --git a/src/lib/support/tests/TestScoped.cpp b/src/lib/support/tests/TestScoped.cpp index fef70a443dcfb1..f89a374e8ee601 100644 --- a/src/lib/support/tests/TestScoped.cpp +++ b/src/lib/support/tests/TestScoped.cpp @@ -18,8 +18,9 @@ #include -#include +#include +#include #include namespace { diff --git a/src/lib/support/tests/TestScopedBuffer.cpp b/src/lib/support/tests/TestScopedBuffer.cpp index c7ec072726c2be..123dca1d2456a7 100644 --- a/src/lib/support/tests/TestScopedBuffer.cpp +++ b/src/lib/support/tests/TestScopedBuffer.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/support/tests/TestSorting.cpp b/src/lib/support/tests/TestSorting.cpp index 1d04604c110fd5..459f41d53b72a7 100644 --- a/src/lib/support/tests/TestSorting.cpp +++ b/src/lib/support/tests/TestSorting.cpp @@ -20,8 +20,9 @@ #include #include -#include +#include +#include #include #include diff --git a/src/lib/support/tests/TestSpan.cpp b/src/lib/support/tests/TestSpan.cpp index 6849138861065c..4813bc460b6be3 100644 --- a/src/lib/support/tests/TestSpan.cpp +++ b/src/lib/support/tests/TestSpan.cpp @@ -24,8 +24,9 @@ #include -#include +#include +#include #include using namespace chip; diff --git a/src/lib/support/tests/TestStateMachine.cpp b/src/lib/support/tests/TestStateMachine.cpp index 4b6af3a73d85cf..3d282b5e5c6e76 100644 --- a/src/lib/support/tests/TestStateMachine.cpp +++ b/src/lib/support/tests/TestStateMachine.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include #include diff --git a/src/lib/support/tests/TestStaticSupportSmartPtr.cpp b/src/lib/support/tests/TestStaticSupportSmartPtr.cpp index 5ffe1cee4d284b..9110c6005b544e 100644 --- a/src/lib/support/tests/TestStaticSupportSmartPtr.cpp +++ b/src/lib/support/tests/TestStaticSupportSmartPtr.cpp @@ -18,8 +18,9 @@ #include -#include +#include +#include #include #include diff --git a/src/lib/support/tests/TestStringBuilder.cpp b/src/lib/support/tests/TestStringBuilder.cpp index 2f4ad518da3dd1..3b0a3299a80c80 100644 --- a/src/lib/support/tests/TestStringBuilder.cpp +++ b/src/lib/support/tests/TestStringBuilder.cpp @@ -14,9 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include +#include + +#include +#include namespace { diff --git a/src/lib/support/tests/TestStringSplitter.cpp b/src/lib/support/tests/TestStringSplitter.cpp index c8dd1e9f802c47..1301049890ac3b 100644 --- a/src/lib/support/tests/TestStringSplitter.cpp +++ b/src/lib/support/tests/TestStringSplitter.cpp @@ -14,9 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include + +#include #include -#include namespace { using namespace chip; diff --git a/src/lib/support/tests/TestTestPersistentStorageDelegate.cpp b/src/lib/support/tests/TestTestPersistentStorageDelegate.cpp index a53f43c0febaaa..f9d403e3d920b0 100644 --- a/src/lib/support/tests/TestTestPersistentStorageDelegate.cpp +++ b/src/lib/support/tests/TestTestPersistentStorageDelegate.cpp @@ -16,15 +16,16 @@ * limitations under the License. */ -#include -#include - #include #include #include #include -#include +#include + +#include +#include +#include using namespace chip; diff --git a/src/lib/support/tests/TestThreadOperationalDataset.cpp b/src/lib/support/tests/TestThreadOperationalDataset.cpp index d9e13c8c25705f..3c60230a573a2a 100644 --- a/src/lib/support/tests/TestThreadOperationalDataset.cpp +++ b/src/lib/support/tests/TestThreadOperationalDataset.cpp @@ -15,8 +15,9 @@ * limitations under the License. */ -#include +#include +#include #include #include @@ -30,11 +31,9 @@ class TestThreadOperationalDataset : public ::testing::Test static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } - static Thread::OperationalDataset dataset; + Thread::OperationalDataset dataset; }; -Thread::OperationalDataset TestThreadOperationalDataset::dataset; - TEST_F(TestThreadOperationalDataset, TestInit) { @@ -103,6 +102,10 @@ TEST_F(TestThreadOperationalDataset, TestMasterKey) EXPECT_EQ(dataset.SetMasterKey(kMasterKey), CHIP_NO_ERROR); EXPECT_EQ(dataset.GetMasterKey(masterKey), CHIP_NO_ERROR); EXPECT_EQ(memcmp(masterKey, kMasterKey, sizeof(kMasterKey)), 0); + + dataset.UnsetMasterKey(); + EXPECT_EQ(dataset.GetMasterKey(masterKey), CHIP_ERROR_TLV_TAG_NOT_FOUND); + EXPECT_EQ(dataset.SetMasterKey(masterKey), CHIP_NO_ERROR); } TEST_F(TestThreadOperationalDataset, TestMeshLocalPrefix) @@ -129,6 +132,7 @@ TEST_F(TestThreadOperationalDataset, TestNetworkName) EXPECT_EQ(dataset.SetNetworkName("0123456789abcdef"), CHIP_NO_ERROR); EXPECT_EQ(dataset.SetNetworkName("0123456789abcdefg"), CHIP_ERROR_INVALID_STRING_LENGTH); EXPECT_EQ(dataset.SetNetworkName(""), CHIP_ERROR_INVALID_STRING_LENGTH); + EXPECT_EQ(dataset.SetNetworkName(nullptr), CHIP_ERROR_INVALID_ARGUMENT); } TEST_F(TestThreadOperationalDataset, TestPanId) @@ -152,25 +156,7 @@ TEST_F(TestThreadOperationalDataset, TestPSKc) EXPECT_EQ(dataset.SetPSKc(kPSKc), CHIP_NO_ERROR); EXPECT_EQ(dataset.GetPSKc(pskc), CHIP_NO_ERROR); EXPECT_FALSE(memcmp(pskc, kPSKc, sizeof(kPSKc))); -} - -TEST_F(TestThreadOperationalDataset, TestUnsetMasterKey) -{ - - uint8_t masterKey[Thread::kSizeMasterKey] = { 0 }; - EXPECT_EQ(dataset.GetMasterKey(masterKey), CHIP_NO_ERROR); - dataset.UnsetMasterKey(); - EXPECT_EQ(dataset.GetMasterKey(masterKey), CHIP_ERROR_TLV_TAG_NOT_FOUND); - EXPECT_EQ(dataset.SetMasterKey(masterKey), CHIP_NO_ERROR); -} - -TEST_F(TestThreadOperationalDataset, TestUnsetPSKc) -{ - - uint8_t pskc[Thread::kSizePSKc] = { 0 }; - - EXPECT_EQ(dataset.GetPSKc(pskc), CHIP_NO_ERROR); dataset.UnsetPSKc(); EXPECT_EQ(dataset.GetPSKc(pskc), CHIP_ERROR_TLV_TAG_NOT_FOUND); EXPECT_EQ(dataset.SetPSKc(pskc), CHIP_NO_ERROR); @@ -178,45 +164,19 @@ TEST_F(TestThreadOperationalDataset, TestUnsetPSKc) TEST_F(TestThreadOperationalDataset, TestClear) { - - { - uint64_t activeTimestamp; - EXPECT_EQ(dataset.GetActiveTimestamp(activeTimestamp), CHIP_NO_ERROR); - } - - { - uint16_t channel; - EXPECT_EQ(dataset.GetChannel(channel), CHIP_NO_ERROR); - } - - { - uint8_t extendedPanId[Thread::kSizeExtendedPanId] = { 0 }; - EXPECT_EQ(dataset.GetExtendedPanId(extendedPanId), CHIP_NO_ERROR); - } - { + EXPECT_EQ(dataset.SetActiveTimestamp(123), CHIP_NO_ERROR); + EXPECT_EQ(dataset.SetChannel(5), CHIP_NO_ERROR); + uint8_t extendedPanId[Thread::kSizeExtendedPanId] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + EXPECT_EQ(dataset.SetExtendedPanId(extendedPanId), CHIP_NO_ERROR); uint8_t masterKey[Thread::kSizeMasterKey] = { 0 }; - EXPECT_EQ(dataset.GetMasterKey(masterKey), CHIP_NO_ERROR); - } - - { + EXPECT_EQ(dataset.SetMasterKey(masterKey), CHIP_NO_ERROR); uint8_t meshLocalPrefix[Thread::kSizeMeshLocalPrefix] = { 0 }; - EXPECT_EQ(dataset.GetMeshLocalPrefix(meshLocalPrefix), CHIP_NO_ERROR); - } - - { - char networkName[Thread::kSizeNetworkName + 1] = { 0 }; - EXPECT_EQ(dataset.GetNetworkName(networkName), CHIP_NO_ERROR); - } - - { - uint16_t panid; - EXPECT_EQ(dataset.GetPanId(panid), CHIP_NO_ERROR); - } - - { + EXPECT_EQ(dataset.SetMeshLocalPrefix(meshLocalPrefix), CHIP_NO_ERROR); + EXPECT_EQ(dataset.SetNetworkName("w00tw00t"), CHIP_NO_ERROR); + EXPECT_EQ(dataset.SetPanId(0x4242), CHIP_NO_ERROR); uint8_t pskc[Thread::kSizePSKc] = { 0 }; - EXPECT_EQ(dataset.GetPSKc(pskc), CHIP_NO_ERROR); + EXPECT_EQ(dataset.SetPSKc(pskc), CHIP_NO_ERROR); } dataset.Clear(); @@ -262,4 +222,103 @@ TEST_F(TestThreadOperationalDataset, TestClear) } } +TEST_F(TestThreadOperationalDataset, TestExampleDataset) +{ + const uint8_t example[] = { + 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // Active Timestamp 1 + 0x00, 0x03, 0x00, 0x00, 0x0f, // Channel 15 + 0x35, 0x04, 0x07, 0xff, 0xf8, 0x00, // Channel Mask 0x07fff800 + 0x02, 0x08, 0x39, 0x75, 0x8e, 0xc8, 0x14, 0x4b, 0x07, 0xfb, // Ext PAN ID 39758ec8144b07fb + 0x07, 0x08, 0xfd, 0xf1, 0xf1, 0xad, 0xd0, 0x79, 0x7d, 0xc0, // Mesh Local Prefix fdf1:f1ad:d079:7dc0::/64 + 0x05, 0x10, 0xf3, 0x66, 0xce, 0xc7, 0xa4, 0x46, 0xba, 0xb9, 0x78, 0xd9, 0x0d, 0x27, 0xab, 0xe3, 0x8f, 0x23, // Network Key + 0x03, 0x0f, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x35, 0x39, 0x33, 0x38, // "OpenThread-5938" + 0x01, 0x02, 0x59, 0x38, // PAN ID : 0x5938 + 0x04, 0x10, 0x3c, 0xa6, 0x7c, 0x96, 0x9e, 0xfb, 0x0d, 0x0c, 0x74, 0xa4, 0xd8, 0xee, 0x92, 0x3b, 0x57, 0x6c, // PKSc + 0x0c, 0x04, 0x02, 0xa0, 0xf7, 0xf8, // Security Policy + }; + EXPECT_EQ(dataset.Init(ByteSpan(example)), CHIP_NO_ERROR); + + uint64_t activeTimestamp; + EXPECT_EQ(dataset.GetActiveTimestamp(activeTimestamp), CHIP_NO_ERROR); + EXPECT_EQ(activeTimestamp, 1u); + + uint16_t channel; + EXPECT_EQ(dataset.GetChannel(channel), CHIP_NO_ERROR); + EXPECT_EQ(channel, 15u); + + uint8_t extPanId[Thread::kSizeExtendedPanId]; + EXPECT_EQ(dataset.GetExtendedPanId(extPanId), CHIP_NO_ERROR); + const uint8_t expectedExtPanId[] = { 0x39, 0x75, 0x8e, 0xc8, 0x14, 0x4b, 0x07, 0xfb }; + EXPECT_TRUE(ByteSpan(extPanId).data_equal(ByteSpan(expectedExtPanId))); + + uint8_t meshLocalPrefix[Thread::kSizeMeshLocalPrefix]; + EXPECT_EQ(dataset.GetMeshLocalPrefix(meshLocalPrefix), CHIP_NO_ERROR); + const uint8_t expectedMeshLocalPrefix[] = { 0xfd, 0xf1, 0xf1, 0xad, 0xd0, 0x79, 0x7d, 0xc0 }; + EXPECT_TRUE(ByteSpan(meshLocalPrefix).data_equal(ByteSpan(expectedMeshLocalPrefix))); + + uint8_t masterKey[Thread::kSizeMasterKey]; + EXPECT_EQ(dataset.GetMasterKey(masterKey), CHIP_NO_ERROR); + const uint8_t expectedMasterKey[] = { 0xf3, 0x66, 0xce, 0xc7, 0xa4, 0x46, 0xba, 0xb9, + 0x78, 0xd9, 0x0d, 0x27, 0xab, 0xe3, 0x8f, 0x23 }; + EXPECT_TRUE(ByteSpan(masterKey).data_equal(ByteSpan(expectedMasterKey))); + + char networkName[Thread::kSizeNetworkName + 1]; + EXPECT_EQ(dataset.GetNetworkName(networkName), CHIP_NO_ERROR); + EXPECT_EQ(strncmp(networkName, "OpenThread-5938", sizeof(networkName)), 0); + + uint16_t panId; + EXPECT_EQ(dataset.GetPanId(panId), CHIP_NO_ERROR); + EXPECT_EQ(panId, 0x5938u); + + uint8_t pksc[Thread::kSizePSKc]; + EXPECT_EQ(dataset.GetPSKc(pksc), CHIP_NO_ERROR); + const uint8_t expectedPksc[] = { + 0x3c, 0xa6, 0x7c, 0x96, 0x9e, 0xfb, 0x0d, 0x0c, 0x74, 0xa4, 0xd8, 0xee, 0x92, 0x3b, 0x57, 0x6c + }; + EXPECT_TRUE(ByteSpan(pksc).data_equal(ByteSpan(expectedPksc))); +} + +TEST_F(TestThreadOperationalDataset, TestInvalidExampleDataset) +{ + const uint8_t invalid[] = { + 0x0e, 0x01, 0x01, // Active Timestamp + 0x00, 0x01, 0x0f, // Channel + 0x35, 0x00, // Channel Mask + 0x02, 0x09, 0x39, 0x75, 0x8e, 0xc8, 0x14, 0x4b, 0x07, 0xfb, 0xff, // Ext PAN ID + 0x07, 0x01, 0x01, // Mesh Local Prefix + 0x05, 0x0f, 0xf3, 0x66, 0xce, 0xc7, 0xa4, 0x46, 0xba, 0xb9, 0x78, 0xd9, 0x0d, 0x27, 0xab, 0xe3, 0x8f, // Network Key + 0x03, 0x11, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x35, 0x39, 0x33, 0x38, 0xff, 0xff, // Name + 0x01, 0x01, 0xff, // PAN ID + 0x04, 0x01, 0x3c, // PKSc + 0x0c, 0x01, 0x01, // Security Policy + }; + + // The overall TLV structure is valid, but all TLVs have invalid sizes + EXPECT_EQ(dataset.Init(ByteSpan(invalid)), CHIP_NO_ERROR); + + uint64_t activeTimestamp; + EXPECT_EQ(dataset.GetActiveTimestamp(activeTimestamp), CHIP_ERROR_INVALID_TLV_ELEMENT); + + uint16_t channel; + EXPECT_EQ(dataset.GetChannel(channel), CHIP_ERROR_INVALID_TLV_ELEMENT); + + ByteSpan extPanId; + EXPECT_EQ(dataset.GetExtendedPanIdAsByteSpan(extPanId), CHIP_ERROR_INVALID_TLV_ELEMENT); + + uint8_t meshLocalPrefix[Thread::kSizeMeshLocalPrefix]; + EXPECT_EQ(dataset.GetMeshLocalPrefix(meshLocalPrefix), CHIP_ERROR_INVALID_TLV_ELEMENT); + + uint8_t masterKey[Thread::kSizeMasterKey]; + EXPECT_EQ(dataset.GetMasterKey(masterKey), CHIP_ERROR_INVALID_TLV_ELEMENT); + + char networkName[Thread::kSizeNetworkName + 1]; + EXPECT_EQ(dataset.GetNetworkName(networkName), CHIP_ERROR_INVALID_TLV_ELEMENT); + + uint16_t panId; + EXPECT_EQ(dataset.GetPanId(panId), CHIP_ERROR_INVALID_TLV_ELEMENT); + + uint8_t pksc[Thread::kSizePSKc]; + EXPECT_EQ(dataset.GetPSKc(pksc), CHIP_ERROR_INVALID_TLV_ELEMENT); +} + } // namespace diff --git a/src/lib/support/tests/TestTimeUtils.cpp b/src/lib/support/tests/TestTimeUtils.cpp index 7d0a69709b8bc4..1b3140399e3c77 100644 --- a/src/lib/support/tests/TestTimeUtils.cpp +++ b/src/lib/support/tests/TestTimeUtils.cpp @@ -29,8 +29,9 @@ #include #include -#include +#include +#include #include #include diff --git a/src/lib/support/tests/TestTlvJson.cpp b/src/lib/support/tests/TestTlvJson.cpp index 83b538dad4a755..a845f5fd08be58 100644 --- a/src/lib/support/tests/TestTlvJson.cpp +++ b/src/lib/support/tests/TestTlvJson.cpp @@ -15,11 +15,12 @@ * limitations under the License. */ -#include +#include #include #include #include +#include #include #include #include diff --git a/src/lib/support/tests/TestTlvToJson.cpp b/src/lib/support/tests/TestTlvToJson.cpp index b313b843616671..4fd807303c251a 100644 --- a/src/lib/support/tests/TestTlvToJson.cpp +++ b/src/lib/support/tests/TestTlvToJson.cpp @@ -17,11 +17,12 @@ #include -#include +#include #include #include #include +#include #include #include #include diff --git a/src/lib/support/tests/TestUtf8.cpp b/src/lib/support/tests/TestUtf8.cpp index dd078804c1ed5d..1a1062630c2ac5 100644 --- a/src/lib/support/tests/TestUtf8.cpp +++ b/src/lib/support/tests/TestUtf8.cpp @@ -17,10 +17,12 @@ * limitations under the License. */ -#include - #include -#include + +#include + +#include +#include namespace { diff --git a/src/lib/support/tests/TestVariant.cpp b/src/lib/support/tests/TestVariant.cpp index cd51d252dd3a0c..cc8e3031306e73 100644 --- a/src/lib/support/tests/TestVariant.cpp +++ b/src/lib/support/tests/TestVariant.cpp @@ -18,8 +18,9 @@ #include -#include +#include +#include #include namespace { diff --git a/src/lib/support/tests/TestZclString.cpp b/src/lib/support/tests/TestZclString.cpp index 13174248af62d7..cecede7fdf53e5 100644 --- a/src/lib/support/tests/TestZclString.cpp +++ b/src/lib/support/tests/TestZclString.cpp @@ -26,8 +26,9 @@ #include #include -#include +#include +#include #include #include #include diff --git a/src/messaging/ExchangeMgr.cpp b/src/messaging/ExchangeMgr.cpp index bf92fa22f54985..0e41593b08afea 100644 --- a/src/messaging/ExchangeMgr.cpp +++ b/src/messaging/ExchangeMgr.cpp @@ -215,16 +215,23 @@ void ExchangeManager::OnMessageReceived(const PacketHeader & packetHeader, const } } + // Work around pigweed not allowing more than 14 format args in a log + // message when using tokenized logs. + char typeStr[4 + 1 + 2 + 1]; + snprintf(typeStr, sizeof(typeStr), "%04X:%02X", payloadHeader.GetProtocolID().GetProtocolId(), payloadHeader.GetMessageType()); + // // Legend that can be used to decode this log line can be found in README.md // - ChipLogProgress(ExchangeManager, - ">>> [E:" ChipLogFormatExchangeId " S:%u M:" ChipLogFormatMessageCounter - "%s] (%s) Msg RX from %u:" ChipLogFormatX64 " [%04X] --- Type %04x:%02x (%s:%s)", - ChipLogValueExchangeIdFromReceivedHeader(payloadHeader), session->SessionIdForLogging(), - packetHeader.GetMessageCounter(), ackBuf, Transport::GetSessionTypeString(session), session->GetFabricIndex(), - ChipLogValueX64(session->GetPeer().GetNodeId()), static_cast(compressedFabricId), - payloadHeader.GetProtocolID().GetProtocolId(), payloadHeader.GetMessageType(), protocolName, msgTypeName); + ChipLogProgress( + ExchangeManager, + ">>> [E:" ChipLogFormatExchangeId " S:%u M:" ChipLogFormatMessageCounter "%s] (%s) Msg RX from %u:" ChipLogFormatX64 + " [%04X] --- Type %s (%s:%s) (B:%u)", + ChipLogValueExchangeIdFromReceivedHeader(payloadHeader), session->SessionIdForLogging(), packetHeader.GetMessageCounter(), + ackBuf, Transport::GetSessionTypeString(session), session->GetFabricIndex(), + ChipLogValueX64(session->GetPeer().GetNodeId()), static_cast(compressedFabricId), typeStr, protocolName, + msgTypeName, + static_cast(msgBuf->TotalLength() + packetHeader.EncodeSizeBytes() + payloadHeader.EncodeSizeBytes())); #endif MessageFlags msgFlags; diff --git a/src/messaging/README.md b/src/messaging/README.md index bfb379e22aa49c..b439a45de6b840 100644 --- a/src/messaging/README.md +++ b/src/messaging/README.md @@ -16,7 +16,7 @@ will be expanded are denoted with `$` . Unless specified, numerical values are represented in decimal notation. ``` -<<< [E:$exchange_id S:$session_id M:$msg_id (Ack: $ack_msg_id)] ($msg_category) Msg TX to $fabric_index:$destination [$compressed_fabric_id] [$peer_address] --- Type $protocol_id:$msg_type ($protocol_name:$msg_type_name) +<<< [E:$exchange_id S:$session_id M:$msg_id (Ack: $ack_msg_id)] ($msg_category) Msg TX to $fabric_index:$destination [$compressed_fabric_id] [$peer_address] --- Type $protocol_id:$msg_type ($protocol_name:$msg_type_name) (B:$size) ``` | Field | Description | @@ -34,6 +34,7 @@ Unless specified, numerical values are represented in decimal notation. | msg_type | 8-bit message type ID (in hex) | | protocol_name | If available, a logical name for the protocol | | msg_type_name | If available, a logical name for the message type | +| size | Size, in bytes, of the message being transmitted. Includes the Matter payload header and packet header but not transport headers | #### Examples: @@ -65,7 +66,7 @@ will be expanded are denoted with `$` . Unless specified, numerical values are represented in decimal notation. ``` ->>> [E:$exchange_id M: $msg_id (Ack: $ack_msg_id)] ($msg_category) Msg RX from $fabric_index:$source [$compressed_fabric_id] --- Type $protocol_id:$msg_type ($protocol_name:$msg_type_name) +>>> [E:$exchange_id M: $msg_id (Ack: $ack_msg_id)] ($msg_category) Msg RX from $fabric_index:$source [$compressed_fabric_id] --- Type $protocol_id:$msg_type ($protocol_name:$msg_type_name) (B:$size) ``` This has a similar legend to that for transmission except `$source` denotes the diff --git a/src/messaging/ReliableMessageProtocolConfig.cpp b/src/messaging/ReliableMessageProtocolConfig.cpp index 01e5779d0c004f..352e89cf4576c1 100644 --- a/src/messaging/ReliableMessageProtocolConfig.cpp +++ b/src/messaging/ReliableMessageProtocolConfig.cpp @@ -32,33 +32,28 @@ #include // 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..24e3f47e6806ae 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", @@ -64,6 +65,7 @@ chip_test_suite("tests") { ":helpers", "${chip_root}/src/inet/tests:helpers", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/messaging", 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..2b3058a8771515 100644 --- a/src/messaging/tests/MessagingContext.h +++ b/src/messaging/tests/MessagingContext.h @@ -16,6 +16,8 @@ */ #pragma once +#include + #include #include #include @@ -92,16 +94,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 +124,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 +162,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 +171,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..6bf161bc157d26 100644 --- a/src/messaging/tests/TestAbortExchangesForFabric.cpp +++ b/src/messaging/tests/TestAbortExchangesForFabric.cpp @@ -21,9 +21,10 @@ * one) for a fabric. */ -#include +#include #include +#include #include #include #include @@ -48,12 +49,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 +59,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..f221c999ac4e22 100644 --- a/src/messaging/tests/TestExchange.cpp +++ b/src/messaging/tests/TestExchange.cpp @@ -17,9 +17,10 @@ #include #include -#include +#include #include +#include #include #include #include @@ -43,10 +44,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 +54,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..cafac38bdcb726 100644 --- a/src/messaging/tests/TestExchangeHolder.cpp +++ b/src/messaging/tests/TestExchangeHolder.cpp @@ -21,10 +21,11 @@ * one) for a fabric. */ -#include +#include #include "messaging/ExchangeDelegate.h" #include "system/SystemClock.h" +#include #include #include #include @@ -68,16 +69,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..679a8cc4050d05 100644 --- a/src/messaging/tests/TestExchangeMgr.cpp +++ b/src/messaging/tests/TestExchangeMgr.cpp @@ -23,9 +23,10 @@ #include #include -#include +#include #include +#include #include #include #include @@ -47,12 +48,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 +57,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..2f16cd97cc51a0 100644 --- a/src/messaging/tests/TestMessagingLayer.cpp +++ b/src/messaging/tests/TestMessagingLayer.cpp @@ -23,9 +23,10 @@ #include #include -#include +#include #include +#include #include #include #include @@ -47,18 +48,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..68b6ed2852d377 100644 --- a/src/messaging/tests/TestReliableMessageProtocol.cpp +++ b/src/messaging/tests/TestReliableMessageProtocol.cpp @@ -23,10 +23,11 @@ */ #include -#include +#include #include #include +#include #include #include #include @@ -60,12 +61,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 +74,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 +498,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 +556,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 +848,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 +896,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/ESP32/ESP32FactoryDataProvider.cpp b/src/platform/ESP32/ESP32FactoryDataProvider.cpp index 4ff4f9d2d29678..95d2be5c5d1957 100644 --- a/src/platform/ESP32/ESP32FactoryDataProvider.cpp +++ b/src/platform/ESP32/ESP32FactoryDataProvider.cpp @@ -98,11 +98,15 @@ CHIP_ERROR ESP32FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifi CHIP_ERROR ESP32FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & outBuffer) { +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + return CopySpanToMutableSpan(mCD, outBuffer); +#else size_t certSize; ReturnErrorOnFailure( ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_CertDeclaration, outBuffer.data(), outBuffer.size(), certSize)); outBuffer.reduce_size(certSize); return CHIP_NO_ERROR; +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API } CHIP_ERROR ESP32FactoryDataProvider::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) @@ -123,15 +127,11 @@ CHIP_ERROR ESP32FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & CHIP_ERROR ESP32FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) { -#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API - return CopySpanToMutableSpan(mCD, outBuffer); -#else size_t certSize; ReturnErrorOnFailure( ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_PAICert, outBuffer.data(), outBuffer.size(), certSize)); outBuffer.reduce_size(certSize); return CHIP_NO_ERROR; -#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API } CHIP_ERROR ESP32FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) 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/nxp/common/ble_zephyr/BLEAdvertisingArbiter.cpp b/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.cpp new file mode 100644 index 00000000000000..e977708fe4862a --- /dev/null +++ b/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.cpp @@ -0,0 +1,138 @@ +/* + * + * 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. + */ + +#include "BLEAdvertisingArbiter.h" + +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace BLEAdvertisingArbiter { +namespace { + +// List of advertising requests ordered by priority +sys_slist_t sRequests; + +// Cast an intrusive list node to the containing request object +const BLEAdvertisingArbiter::Request & ToRequest(const sys_snode_t * node) +{ + return *static_cast(node); +} + +// Notify application about stopped advertising if the callback has been provided +void NotifyAdvertisingStopped(const sys_snode_t * node) +{ + VerifyOrReturn(node); + + const Request & request = ToRequest(node); + + if (request.onStopped != nullptr) + { + request.onStopped(); + } +} + +// Restart advertising using the top-priority request +CHIP_ERROR RestartAdvertising() +{ + // Note: bt_le_adv_stop() returns success when the advertising was not started + ReturnErrorOnFailure(MapErrorZephyr(bt_le_adv_stop())); + ReturnErrorCodeIf(sys_slist_is_empty(&sRequests), CHIP_NO_ERROR); + + const Request & top = ToRequest(sys_slist_peek_head(&sRequests)); + const bt_le_adv_param params = BT_LE_ADV_PARAM_INIT(top.options, top.minInterval, top.maxInterval, nullptr); + const int result = bt_le_adv_start(¶ms, top.advertisingData.data(), top.advertisingData.size(), top.scanResponseData.data(), + top.scanResponseData.size()); + + if (top.onStarted != nullptr) + { + top.onStarted(result); + } + + return MapErrorZephyr(result); +} + +} // namespace + +CHIP_ERROR InsertRequest(Request & request) +{ + CancelRequest(request); + + sys_snode_t * prev = nullptr; + sys_snode_t * node = nullptr; + + // Find position of the request in the list that preserves ordering by priority + SYS_SLIST_FOR_EACH_NODE(&sRequests, node) + { + if (request.priority < ToRequest(node).priority) + { + break; + } + + prev = node; + } + + if (prev == nullptr) + { + NotifyAdvertisingStopped(sys_slist_peek_head(&sRequests)); + sys_slist_prepend(&sRequests, &request); + } + else + { + sys_slist_insert(&sRequests, prev, &request); + } + + // If the request is top-priority, restart the advertising + if (sys_slist_peek_head(&sRequests) == &request) + { + return RestartAdvertising(); + } + + return CHIP_NO_ERROR; +} + +void CancelRequest(Request & request) +{ + const bool isTopPriority = (sys_slist_peek_head(&sRequests) == &request); + VerifyOrReturn(sys_slist_find_and_remove(&sRequests, &request)); + + // If cancelled request was top-priority, restart the advertising. + if (isTopPriority) + { + RestartAdvertising(); + } +} + +} // namespace BLEAdvertisingArbiter + +/** + * This implements a mapping function for CHIP System Layer errors that allows mapping integers in the number space of the + * Zephyr OS user API stack errors into the POSIX range. + * + * @param[in] aError The native Zephyr API error to map. + * + * @return The mapped POSIX error. + */ +DLL_EXPORT CHIP_ERROR MapErrorZephyr(int aError) +{ + return chip::System::Internal::MapErrorPOSIX(-aError); +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.h b/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.h new file mode 100644 index 00000000000000..9c00edbb8e746d --- /dev/null +++ b/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.h @@ -0,0 +1,107 @@ +/* + * + * 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. + */ + +#pragma once + +#include + +#include +#include + +#include + +/** + * @file + * Bluetooth LE advertising arbiter. + * + * The purpose for this module is to coordinate BLE advertising between + * different application components. + * + * An application component that wants to advertise BLE services is expected to + * define a request with a desired priority, and pass it to the BLE advertising + * arbiter. If there are multiple components that request BLE advertising at the + * same time, the arbiter selects the one with the highest priority (represented + * by the lowest numeric value) and starts the BLE advertising using parameters + * defined in the winning request. + * + * The BLE arbiter does not take ownership of a submitted request, so the + * request object must be sustained until it is cancelled by the application. + */ + +namespace chip { +namespace DeviceLayer { +namespace BLEAdvertisingArbiter { + +using OnAdvertisingStarted = void (*)(int result); +using OnAdvertisingStopped = void (*)(); + +struct Request : public sys_snode_t +{ + uint8_t priority; ///< Advertising request priority. Lower value means higher priority + uint32_t options; ///< Advertising options: bitmask of BT_LE_ADV_OPT_XXX constants from Zephyr + uint16_t minInterval; ///< Minimum advertising interval in 0.625 ms units + uint16_t maxInterval; ///< Maximum advertising interval in 0.625 ms units + Span advertisingData; ///< Advertising data fields + Span scanResponseData; ///< Scan response data fields + OnAdvertisingStarted onStarted; ///< (Optional) Callback invoked when the request becomes top-priority. + OnAdvertisingStopped onStopped; ///< (Optional) Callback invoked when the request stops being top-priority. +}; + +/** + * @brief Request BLE advertising + * + * Add the request to the internal list of competing requests. If the request + * has higher priority than other requests in the list, restart the BLE + * advertising immediately using parameters defined in the new request. + * + * Inserting a request object that is already registered at the advertising + * arbiter automatically cancels the previous request. + * + * @note This method does not take ownership of the request object so the object + * must not get destroyed before it is cancelled. + * + * @param request Reference to advertising request that contains priority and + * other advertising parameters. + * @return error If the request is top-priority and failed to restart the + * advertising. + * @return success Otherwise. + */ +CHIP_ERROR InsertRequest(Request & request); + +/** + * @brief Cancel BLE advertising request + * + * Remove the request from the internal list of competing requests. If the + * request is the winning (top-priority) one at the time of calling this + * function, restart the BLE advertising using parameters defined in the 2nd + * top-priority request in the list, or stop the BLE advertising completely if + * this is the last request in the list. + * + * An attempt to cancel a request that has not been registered at the + * advertising arbiter is a no-op. That is, it returns immediately. + * + * @param request Reference to advertising request that contains priority and + * other advertising parameters. + */ +void CancelRequest(Request & request); + +} // namespace BLEAdvertisingArbiter + +extern CHIP_ERROR MapErrorZephyr(int code); + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/common/ble_zephyr/BLEManagerImpl.cpp b/src/platform/nxp/common/ble_zephyr/BLEManagerImpl.cpp new file mode 100644 index 00000000000000..0b986033054fbe --- /dev/null +++ b/src/platform/nxp/common/ble_zephyr/BLEManagerImpl.cpp @@ -0,0 +1,849 @@ +/* + * + * Copyright (c) 2020-2022, 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. + */ + +/** + * @file + * Provides an implementation of the BLEManager singleton object + * for Zephyr platforms. + */ + +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +#include "BLEManagerImpl.h" + +#include +#include +#include +#include +#include +#include +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include + +using namespace ::chip; +using namespace ::chip::Ble; +using namespace ::chip::System; + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +namespace { + +constexpr uint32_t kAdvertisingOptions = BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME; +constexpr uint8_t kAdvertisingFlags = BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR; + +const bt_uuid_128 UUID128_CHIPoBLEChar_RX = + BT_UUID_INIT_128(0x11, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18); +const bt_uuid_128 UUID128_CHIPoBLEChar_TX = + BT_UUID_INIT_128(0x12, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18); +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +const bt_uuid_128 UUID128_CHIPoBLEChar_C3 = + BT_UUID_INIT_128(0x04, 0x8F, 0x21, 0x83, 0x8A, 0x74, 0x7D, 0xB8, 0xF2, 0x45, 0x72, 0x87, 0x38, 0x02, 0x63, 0x64); +#endif + +bt_uuid_16 UUID16_CHIPoBLEService = BT_UUID_INIT_16(0xFFF6); + +const ChipBleUUID chipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, + 0x9D, 0x11 } }; + +const ChipBleUUID chipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, + 0x9D, 0x12 } }; + +_bt_gatt_ccc CHIPoBLEChar_TX_CCC = BT_GATT_CCC_INITIALIZER(nullptr, BLEManagerImpl::HandleTXCCCWrite, nullptr); + +// clang-format off + +bt_gatt_attr sChipoBleAttributes[] = { + BT_GATT_PRIMARY_SERVICE(&UUID16_CHIPoBLEService.uuid), + BT_GATT_CHARACTERISTIC(&UUID128_CHIPoBLEChar_RX.uuid, + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP, + BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, + nullptr, BLEManagerImpl::HandleRXWrite, nullptr), + BT_GATT_CHARACTERISTIC(&UUID128_CHIPoBLEChar_TX.uuid, + BT_GATT_CHRC_INDICATE, + BT_GATT_PERM_NONE, + nullptr, nullptr, nullptr), + BT_GATT_CCC_MANAGED(&CHIPoBLEChar_TX_CCC, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + BT_GATT_CHARACTERISTIC(&UUID128_CHIPoBLEChar_C3.uuid, + BT_GATT_CHRC_READ, + BT_GATT_PERM_READ, + BLEManagerImpl::HandleC3Read, nullptr, nullptr), +#endif +}; + +bt_gatt_service sChipoBleService = BT_GATT_SERVICE(sChipoBleAttributes); + +// clang-format on + +// Index of the CCC descriptor in the CHIPoBLE_Service array of attributes. +// This value should be adjusted accordingly if the service declaration changes. +constexpr int kCHIPoBLE_CCC_AttributeIndex = 3; + +CHIP_ERROR InitRandomStaticAddress() +{ + // Generate a random static address for the default identity. + // This must be done before bt_enable() as after that updating the default identity is not possible. + int error = 0; + bt_addr_le_t addr; + + // generating the address + addr.type = BT_ADDR_LE_RANDOM; + error = sys_csrand_get(addr.a.val, sizeof(addr.a.val)); + BT_ADDR_SET_STATIC(&addr.a); + + if (error) + { + ChipLogError(DeviceLayer, "Failed to create BLE address: %d", error); + return MapErrorZephyr(error); + } + + error = bt_id_create(&addr, nullptr); + + if (error < 0) + { + ChipLogError(DeviceLayer, "Failed to create BLE identity: %d", error); + return MapErrorZephyr(error); + } + + ChipLogProgress(DeviceLayer, "BLE address: %02X:%02X:%02X:%02X:%02X:%02X", addr.a.val[5], addr.a.val[4], addr.a.val[3], + addr.a.val[2], addr.a.val[1], addr.a.val[0]); + return CHIP_NO_ERROR; +} + +} // unnamed namespace + +BLEManagerImpl BLEManagerImpl::sInstance; + +CHIP_ERROR BLEManagerImpl::_Init() +{ + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled; + mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART); + mFlags.Set(Flags::kFastAdvertisingEnabled, true); + mGAPConns = 0; + + memset(mSubscribedConns, 0, sizeof(mSubscribedConns)); + + ReturnErrorOnFailure(InitRandomStaticAddress()); + int err = bt_enable(NULL); + VerifyOrReturnError(err == 0, MapErrorZephyr(err)); + + memset(&mConnCallbacks, 0, sizeof(mConnCallbacks)); + mConnCallbacks.connected = HandleConnect; + mConnCallbacks.disconnected = HandleDisconnect; + + bt_conn_cb_register(&mConnCallbacks); + + // Initialize the CHIP BleLayer. + ReturnErrorOnFailure(BleLayer::Init(this, this, &DeviceLayer::SystemLayer())); + + PlatformMgr().ScheduleWork(DriveBLEState, 0); + + return CHIP_NO_ERROR; +} + +void BLEManagerImpl::DriveBLEState(intptr_t arg) +{ + BLEMgrImpl().DriveBLEState(); +} + +void BLEManagerImpl::DriveBLEState() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Perform any initialization actions that must occur after the CHIP task is running. + if (!mFlags.Has(Flags::kAsyncInitCompleted)) + { + mFlags.Set(Flags::kAsyncInitCompleted); + } + + // If the application has enabled CHIPoBLE and BLE advertising... + if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && + mFlags.Has(Flags::kAdvertisingEnabled) +#if CHIP_DEVICE_CONFIG_CHIPOBLE_SINGLE_CONNECTION + // and no connections are active... + && (NumConnections() == 0) +#endif + ) + { + // Start/re-start advertising if not already advertising, or if the + // advertising state needs to be refreshed. + if (!mFlags.Has(Flags::kAdvertising) || mFlags.Has(Flags::kAdvertisingRefreshNeeded)) + { + mFlags.Clear(Flags::kAdvertisingRefreshNeeded); + err = StartAdvertising(); + SuccessOrExit(err); + } + } + else + { + if (mFlags.Has(Flags::kAdvertising)) + { + err = StopAdvertising(); + SuccessOrExit(err); + } + + // If no connections are active unregister also CHIPoBLE GATT service + if (NumConnections() == 0 && mFlags.Has(Flags::kChipoBleGattServiceRegister)) + { + // Unregister CHIPoBLE service to not allow discovering it when pairing is disabled. + if (bt_gatt_service_unregister(&sChipoBleService) != 0) + { + ChipLogError(DeviceLayer, "Failed to unregister CHIPoBLE GATT service"); + } + else + { + mFlags.Clear(Flags::kChipoBleGattServiceRegister); + } + } + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %" CHIP_ERROR_FORMAT, err.Format()); + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; + } +} + +struct BLEManagerImpl::ServiceData +{ + uint8_t uuid[2]; + ChipBLEDeviceIdentificationInfo deviceIdInfo; +} __attribute__((packed)); + +inline CHIP_ERROR BLEManagerImpl::PrepareAdvertisingRequest() +{ + static ServiceData serviceData; + static std::array advertisingData; + static std::array scanResponseData; + static_assert(sizeof(serviceData) == 10, "Unexpected size of BLE advertising data!"); + + const char * name = bt_get_name(); + const uint8_t nameSize = static_cast(strlen(name)); + + Encoding::LittleEndian::Put16(serviceData.uuid, UUID16_CHIPoBLEService.val); + ReturnErrorOnFailure(ConfigurationMgr().GetBLEDeviceIdentificationInfo(serviceData.deviceIdInfo)); + + advertisingData[0] = BT_DATA(BT_DATA_FLAGS, &kAdvertisingFlags, sizeof(kAdvertisingFlags)); + advertisingData[1] = BT_DATA(BT_DATA_SVC_DATA16, &serviceData, sizeof(serviceData)); + scanResponseData[0] = BT_DATA(BT_DATA_NAME_COMPLETE, name, nameSize); + + mAdvertisingRequest.priority = CHIP_DEVICE_BLE_ADVERTISING_PRIORITY; + mAdvertisingRequest.options = kAdvertisingOptions; + mAdvertisingRequest.minInterval = mFlags.Has(Flags::kFastAdvertisingEnabled) + ? CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MIN + : CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN; + mAdvertisingRequest.maxInterval = mFlags.Has(Flags::kFastAdvertisingEnabled) + ? CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX + : CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX; + mAdvertisingRequest.advertisingData = Span(advertisingData); + mAdvertisingRequest.scanResponseData = nameSize ? Span(scanResponseData) : Span{}; + + mAdvertisingRequest.onStarted = [](int rc) { + if (rc == 0) + { + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising started"); + } + else + { + ChipLogError(DeviceLayer, "Failed to start CHIPoBLE advertising: %d", rc); + } + }; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::StartAdvertising() +{ + // Prepare advertising request + ReturnErrorOnFailure(PrepareAdvertisingRequest()); + + // Register dynamically CHIPoBLE GATT service + if (!mFlags.Has(Flags::kChipoBleGattServiceRegister)) + { + int err = bt_gatt_service_register(&sChipoBleService); + + if (err != 0) + ChipLogError(DeviceLayer, "Failed to register CHIPoBLE GATT service"); + + VerifyOrReturnError(err == 0, MapErrorZephyr(err)); + + mFlags.Set(Flags::kChipoBleGattServiceRegister); + } + + // Initialize C3 characteristic data +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + ReturnErrorOnFailure(PrepareC3CharData()); +#endif + + // Request advertising + ReturnErrorOnFailure(BLEAdvertisingArbiter::InsertRequest(mAdvertisingRequest)); + + // Transition to the Advertising state... + if (!mFlags.Has(Flags::kAdvertising)) + { + mFlags.Set(Flags::kAdvertising); + + // Post a CHIPoBLEAdvertisingChange(Started) event. + { + ChipDeviceEvent advChange; + advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; + advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Started; + ReturnErrorOnFailure(PlatformMgr().PostEvent(&advChange)); + } + + if (mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + // Start timer to change advertising interval. + DeviceLayer::SystemLayer().StartTimer( + System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME), + HandleBLEAdvertisementIntervalChange, this); + } + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::StopAdvertising() +{ + BLEAdvertisingArbiter::CancelRequest(mAdvertisingRequest); + + // Transition to the not Advertising state... + if (mFlags.Has(Flags::kAdvertising)) + { + mFlags.Clear(Flags::kAdvertising); + mFlags.Set(Flags::kFastAdvertisingEnabled, true); + + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising stopped"); + + // Post a CHIPoBLEAdvertisingChange(Stopped) event. + { + ChipDeviceEvent advChange; + advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; + advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; + ReturnErrorOnFailure(PlatformMgr().PostEvent(&advChange)); + } + + // Cancel timer event changing CHIPoBLE advertisement interval + DeviceLayer::SystemLayer().CancelTimer(HandleBLEAdvertisementIntervalChange, this); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) +{ + if (mFlags.Has(Flags::kAdvertisingEnabled) != val) + { + ChipLogDetail(DeviceLayer, "CHIPoBLE advertising set to %s", val ? "on" : "off"); + + mFlags.Set(Flags::kAdvertisingEnabled, val); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) +{ + switch (mode) + { + case BLEAdvertisingMode::kFastAdvertising: + mFlags.Set(Flags::kFastAdvertisingEnabled, true); + break; + case BLEAdvertisingMode::kSlowAdvertising: + mFlags.Set(Flags::kFastAdvertisingEnabled, false); + break; + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + mFlags.Set(Flags::kAdvertisingRefreshNeeded); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize) +{ + Platform::CopyString(buf, bufSize, bt_get_name()); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * deviceName) +{ + ChipLogDetail(DeviceLayer, "Device name set to: %s", deviceName); + return MapErrorZephyr(bt_set_name(deviceName)); +} + +CHIP_ERROR BLEManagerImpl::HandleGAPConnect(const ChipDeviceEvent * event) +{ + const BleConnEventType * connEvent = &event->Platform.BleConnEvent; + + if (connEvent->HciResult == BT_HCI_ERR_SUCCESS) + { + ChipLogProgress(DeviceLayer, "BLE connection established (ConnId: 0x%02x)", bt_conn_index(connEvent->BtConn)); + mGAPConns++; + } + else + { + ChipLogError(DeviceLayer, "BLE connection failed (reason: 0x%02x)", connEvent->HciResult); + } + + ChipLogProgress(DeviceLayer, "Current number of connections: %u/%u", NumConnections(), CONFIG_BT_MAX_CONN); + + mFlags.Set(Flags::kAdvertisingRefreshNeeded); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + + bt_conn_unref(connEvent->BtConn); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::HandleGAPDisconnect(const ChipDeviceEvent * event) +{ + const BleConnEventType * connEvent = &event->Platform.BleConnEvent; + + ChipLogProgress(DeviceLayer, "BLE GAP connection terminated (reason 0x%02x)", connEvent->HciResult); + + mGAPConns--; + + // If indications were enabled for this connection, record that they are now disabled and + // notify the BLE Layer of a disconnect. + if (UnsetSubscribed(connEvent->BtConn)) + { + CHIP_ERROR disconReason; + switch (connEvent->HciResult) + { + case BT_HCI_ERR_REMOTE_USER_TERM_CONN: + // Do not treat proper connection termination as an error and exit. + VerifyOrExit(!ConfigurationMgr().IsFullyProvisioned(), ); + disconReason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED; + break; + case BT_HCI_ERR_LOCALHOST_TERM_CONN: + disconReason = BLE_ERROR_APP_CLOSED_CONNECTION; + break; + default: + disconReason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT; + break; + } + HandleConnectionError(connEvent->BtConn, disconReason); + } + +exit: + // Unref bt_conn before scheduling DriveBLEState. + bt_conn_unref(connEvent->BtConn); + + ChipLogProgress(DeviceLayer, "Current number of connections: %u/%u", NumConnections(), CONFIG_BT_MAX_CONN); + + ChipDeviceEvent disconnectEvent; + disconnectEvent.Type = DeviceEventType::kCHIPoBLEConnectionClosed; + ReturnErrorOnFailure(PlatformMgr().PostEvent(&disconnectEvent)); + + // Force a reconfiguration of advertising in case we switched to non-connectable mode when + // the BLE connection was established. + mFlags.Set(Flags::kAdvertisingRefreshNeeded); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::HandleTXCharCCCDWrite(const ChipDeviceEvent * event) +{ + const BleCCCWriteEventType * writeEvent = &event->Platform.BleCCCWriteEvent; + + ChipLogDetail(DeviceLayer, "ConnId: 0x%02x, New CCCD value: 0x%04x", bt_conn_index(writeEvent->BtConn), writeEvent->Value); + + // If the client has requested to enable indications and if it is not yet subscribed + if (writeEvent->Value == BT_GATT_CCC_INDICATE && SetSubscribed(writeEvent->BtConn)) + { + // Alert the BLE layer that CHIPoBLE "subscribe" has been received and increment the bt_conn reference counter. + HandleSubscribeReceived(writeEvent->BtConn, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + + ChipLogProgress(DeviceLayer, "CHIPoBLE connection established (ConnId: 0x%02x, GATT MTU: %u)", + bt_conn_index(writeEvent->BtConn), GetMTU(writeEvent->BtConn)); + + // Post a CHIPoBLEConnectionEstablished event to the DeviceLayer and the application. + { + ChipDeviceEvent conEstEvent; + conEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; + ReturnErrorOnFailure(PlatformMgr().PostEvent(&conEstEvent)); + } + } + else + { + if (UnsetSubscribed(writeEvent->BtConn)) + { + HandleUnsubscribeReceived(writeEvent->BtConn, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + } + } + + bt_conn_unref(writeEvent->BtConn); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::HandleRXCharWrite(const ChipDeviceEvent * event) +{ + const BleC1WriteEventType * c1WriteEvent = &event->Platform.BleC1WriteEvent; + + ChipLogDetail(DeviceLayer, "Write request received for CHIPoBLE RX characteristic (ConnId 0x%02x)", + bt_conn_index(c1WriteEvent->BtConn)); + + HandleWriteReceived(c1WriteEvent->BtConn, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_RX, + PacketBufferHandle::Adopt(c1WriteEvent->Data)); + bt_conn_unref(c1WriteEvent->BtConn); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::HandleTXCharComplete(const ChipDeviceEvent * event) +{ + const BleC2IndDoneEventType * c2IndDoneEvent = &event->Platform.BleC2IndDoneEvent; + + ChipLogDetail(DeviceLayer, "Indication for CHIPoBLE TX characteristic done (ConnId 0x%02x, result 0x%02x)", + bt_conn_index(c2IndDoneEvent->BtConn), c2IndDoneEvent->Result); + + // Signal the BLE Layer that the outstanding indication is complete. + HandleIndicationConfirmation(c2IndDoneEvent->BtConn, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + bt_conn_unref(c2IndDoneEvent->BtConn); + + return CHIP_NO_ERROR; +} + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +CHIP_ERROR BLEManagerImpl::PrepareC3CharData() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + BitFlags additionalDataFields; + AdditionalDataPayloadGeneratorParams additionalDataPayloadParams; + +#if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID) + uint8_t rotatingDeviceIdUniqueId[ConfigurationManager::kRotatingDeviceIDUniqueIDLength] = {}; + MutableByteSpan rotatingDeviceIdUniqueIdSpan(rotatingDeviceIdUniqueId); + + err = DeviceLayer::GetDeviceInstanceInfoProvider()->GetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueIdSpan); + SuccessOrExit(err); + err = ConfigurationMgr().GetLifetimeCounter(additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter); + SuccessOrExit(err); + additionalDataPayloadParams.rotatingDeviceIdUniqueId = rotatingDeviceIdUniqueIdSpan; + additionalDataFields.Set(AdditionalDataFields::RotatingDeviceId); +#endif /* CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID) */ + + err = AdditionalDataPayloadGenerator().generateAdditionalDataPayload(additionalDataPayloadParams, c3CharDataBufferHandle, + additionalDataFields); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to generate TLV encoded Additional Data (%s)", __func__); + } + + return err; +} +#endif + +void BLEManagerImpl::HandleBLEAdvertisementIntervalChange(System::Layer * layer, void * param) +{ + BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising); + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising mode changed to slow"); +} + +void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + switch (event->Type) + { + case DeviceEventType::kPlatformZephyrBleConnected: + err = HandleGAPConnect(event); + break; + + case DeviceEventType::kPlatformZephyrBleDisconnected: + err = HandleGAPDisconnect(event); + break; + + case DeviceEventType::kPlatformZephyrBleCCCWrite: + err = HandleTXCharCCCDWrite(event); + break; + + case DeviceEventType::kPlatformZephyrBleC1WriteEvent: + err = HandleRXCharWrite(event); + break; + + case DeviceEventType::kPlatformZephyrBleC2IndDoneEvent: + err = HandleTXCharComplete(event); + break; + + default: + break; + } + + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %" CHIP_ERROR_FORMAT, err.Format()); + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } +} + +uint16_t BLEManagerImpl::_NumConnections(void) +{ + return mGAPConns; +} + +bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId) +{ + ChipLogProgress(DeviceLayer, "Closing BLE GATT connection (ConnId %02x)", bt_conn_index(conId)); + return bt_conn_disconnect(conId, BT_HCI_ERR_REMOTE_USER_TERM_CONN) == 0; +} + +uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const +{ + return bt_gatt_get_mtu(conId); +} + +bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogDetail(DeviceLayer, "BLE central not implemented"); + return false; +} + +bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogDetail(DeviceLayer, "BLE central not implemented"); + return false; +} + +bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + int status = 0; + uint8_t index = bt_conn_index(conId); + bt_gatt_indicate_params * params = &mIndicateParams[index]; + + VerifyOrExit(IsSubscribed(conId) == true, err = CHIP_ERROR_INVALID_ARGUMENT); + + ChipLogDetail(DeviceLayer, "Sending indication for CHIPoBLE TX characteristic (ConnId %02x, len %u)", index, + pBuf->DataLength()); + + params->uuid = nullptr; + params->attr = &sChipoBleAttributes[kCHIPoBLE_CCC_AttributeIndex]; + params->func = HandleTXIndicated; + params->data = pBuf->Start(); + params->len = pBuf->DataLength(); + + status = bt_gatt_indicate(conId, params); + VerifyOrExit(status == 0, err = MapErrorZephyr(status)); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "BLEManagerImpl::SendIndication() failed: %" CHIP_ERROR_FORMAT, err.Format()); + } + + return err == CHIP_NO_ERROR; +} + +bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + ChipLogDetail(DeviceLayer, "BLE central not implemented"); + return false; +} + +bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + ChipLogDetail(DeviceLayer, "BLE central not implemented"); + return false; +} + +bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, + const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogDetail(DeviceLayer, "BLE central not implemented"); + return false; +} + +void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) +{ + CloseConnection(conId); +} + +bool BLEManagerImpl::IsSubscribed(bt_conn * conn) +{ + return mSubscribedConns[bt_conn_index(conn)]; +} + +bool BLEManagerImpl::SetSubscribed(bt_conn * conn) +{ + uint8_t index = bt_conn_index(conn); + bool isSubscribed = mSubscribedConns[index]; + mSubscribedConns[index] = true; + + // If we were not subscribed previously, increment the reference counter of the connection. + if (!isSubscribed) + { + bt_conn_ref(conn); + } + + return !isSubscribed; +} + +bool BLEManagerImpl::UnsetSubscribed(bt_conn * conn) +{ + uint8_t index = bt_conn_index(conn); + bool isSubscribed = mSubscribedConns[index]; + mSubscribedConns[index] = false; + + // If we were subscribed previously, decrement the reference counter of the connection. + if (isSubscribed) + { + bt_conn_unref(conn); + } + + return isSubscribed; +} + +ssize_t BLEManagerImpl::HandleRXWrite(struct bt_conn * conId, const struct bt_gatt_attr * attr, const void * buf, uint16_t len, + uint16_t offset, uint8_t flags) +{ + ChipDeviceEvent event; + PacketBufferHandle packetBuf = PacketBufferHandle::NewWithData(buf, len); + + if (!packetBuf.IsNull()) + { + // Arrange to post a CHIPoBLERXWriteEvent event to the CHIP queue. + event.Type = DeviceEventType::kPlatformZephyrBleC1WriteEvent; + event.Platform.BleC1WriteEvent.BtConn = bt_conn_ref(conId); + event.Platform.BleC1WriteEvent.Data = std::move(packetBuf).UnsafeRelease(); + } + + // If we failed to allocate a buffer, post a kPlatformZephyrBleOutOfBuffersEvent event. + else + { + event.Type = DeviceEventType::kPlatformZephyrBleOutOfBuffersEvent; + } + + PlatformMgr().PostEventOrDie(&event); + + return len; +} + +ssize_t BLEManagerImpl::HandleTXCCCWrite(struct bt_conn * conId, const struct bt_gatt_attr * attr, uint16_t value) +{ + ChipDeviceEvent event; + + if (value != BT_GATT_CCC_INDICATE && value != 0) + { + return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED); + } + + event.Type = DeviceEventType::kPlatformZephyrBleCCCWrite; + event.Platform.BleCCCWriteEvent.BtConn = bt_conn_ref(conId); + event.Platform.BleCCCWriteEvent.Value = value; + + PlatformMgr().PostEventOrDie(&event); + + return sizeof(value); +} + +void BLEManagerImpl::HandleTXIndicated(struct bt_conn * conId, bt_gatt_indicate_params *, uint8_t err) +{ + ChipDeviceEvent event; + + event.Type = DeviceEventType::kPlatformZephyrBleC2IndDoneEvent; + event.Platform.BleC2IndDoneEvent.BtConn = bt_conn_ref(conId); + event.Platform.BleC2IndDoneEvent.Result = err; + + PlatformMgr().PostEventOrDie(&event); +} + +void BLEManagerImpl::HandleConnect(struct bt_conn * conId, uint8_t err) +{ + ChipDeviceEvent event; + + PlatformMgr().LockChipStack(); + + // Don't handle BLE connecting events when it is not related to CHIPoBLE + VerifyOrExit(sInstance.mFlags.Has(Flags::kChipoBleGattServiceRegister), ); + + event.Type = DeviceEventType::kPlatformZephyrBleConnected; + event.Platform.BleConnEvent.BtConn = bt_conn_ref(conId); + event.Platform.BleConnEvent.HciResult = err; + + PlatformMgr().PostEventOrDie(&event); + +exit: + PlatformMgr().UnlockChipStack(); +} + +void BLEManagerImpl::HandleDisconnect(struct bt_conn * conId, uint8_t reason) +{ + ChipDeviceEvent event; + + PlatformMgr().LockChipStack(); + + // Don't handle BLE disconnecting events when it is not related to CHIPoBLE + VerifyOrExit(sInstance.mFlags.Has(Flags::kChipoBleGattServiceRegister), ); + + event.Type = DeviceEventType::kPlatformZephyrBleDisconnected; + event.Platform.BleConnEvent.BtConn = bt_conn_ref(conId); + event.Platform.BleConnEvent.HciResult = reason; + + PlatformMgr().PostEventOrDie(&event); + +exit: + PlatformMgr().UnlockChipStack(); +} + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +ssize_t BLEManagerImpl::HandleC3Read(struct bt_conn * conId, const struct bt_gatt_attr * attr, void * buf, uint16_t len, + uint16_t offset) +{ + ChipLogDetail(DeviceLayer, "Read request received for CHIPoBLE C3 (ConnId 0x%02x)", bt_conn_index(conId)); + + if (sInstance.c3CharDataBufferHandle.IsNull()) + { + return 0; + } + + return bt_gatt_attr_read(conId, attr, buf, len, offset, sInstance.c3CharDataBufferHandle->Start(), + sInstance.c3CharDataBufferHandle->DataLength()); +} +#endif + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/nxp/common/ble_zephyr/BLEManagerImpl.h b/src/platform/nxp/common/ble_zephyr/BLEManagerImpl.h index 411392aa3c6a8c..e80faebe45abc1 100644 --- a/src/platform/nxp/common/ble_zephyr/BLEManagerImpl.h +++ b/src/platform/nxp/common/ble_zephyr/BLEManagerImpl.h @@ -1,8 +1,6 @@ /* * - * Copyright (c) 2020-2021 Project CHIP Authors - * Copyright (c) 2020 Nest Labs, Inc. - * All rights reserved. + * Copyright (c) 2020-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. @@ -20,12 +18,180 @@ /** * @file * Provides an implementation of the BLEManager singleton object - * for the nxp platforms. + * for the NXP platforms. */ #pragma once +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +#include "BLEAdvertisingArbiter.h" + +#include +#include +#include + #include -#include #include #include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +using namespace chip::Ble; + +/** + * Concrete implementation of the BLEManager singleton object for the Zephyr platforms. + */ +class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePlatformDelegate, private BleApplicationDelegate +{ + // Allow the BLEManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend BLEManager; + +private: + // ===== Members that implement the BLEManager internal interface. + + CHIP_ERROR _Init(void); + void _Shutdown() {} + bool _IsAdvertisingEnabled(void); + CHIP_ERROR _SetAdvertisingEnabled(bool val); + bool _IsAdvertising(void); + CHIP_ERROR _SetAdvertisingMode(BLEAdvertisingMode mode); + CHIP_ERROR _GetDeviceName(char * buf, size_t bufSize); + CHIP_ERROR _SetDeviceName(const char * deviceName); + uint16_t _NumConnections(void); + void _OnPlatformEvent(const ChipDeviceEvent * event); + BleLayer * _GetBleLayer(void); + + // ===== Members that implement virtual methods on BlePlatformDelegate. + + bool SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId); + bool UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId); + bool CloseConnection(BLE_CONNECTION_OBJECT conId); + uint16_t GetMTU(BLE_CONNECTION_OBJECT conId) const; + bool SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf); + bool SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf); + bool SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf); + bool SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, const ChipBleUUID * svcId, + const ChipBleUUID * charId); + + // ===== Members that implement virtual methods on BleApplicationDelegate. + + void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId); + + // ===== Private members reserved for use by this class only. + + enum class Flags : uint8_t + { + kAsyncInitCompleted = 0x0001, /**< One-time asynchronous initialization actions have been performed. */ + kAdvertisingEnabled = 0x0002, /**< The application has enabled CHIPoBLE advertising. */ + kFastAdvertisingEnabled = 0x0004, /**< The application has enabled fast advertising. */ + kAdvertising = 0x0008, /**< The system is currently CHIPoBLE advertising. */ + kAdvertisingRefreshNeeded = + 0x0010, /**< The advertising state/configuration has changed, but the SoftDevice has yet to be updated. */ + kChipoBleGattServiceRegister = 0x0020, /**< The system has currently CHIPoBLE GATT service registered. */ + }; + + struct ServiceData; + + BitFlags mFlags; + uint16_t mGAPConns; + CHIPoBLEServiceMode mServiceMode; + bool mSubscribedConns[CONFIG_BT_MAX_CONN]; + bt_gatt_indicate_params mIndicateParams[CONFIG_BT_MAX_CONN]; + bt_conn_cb mConnCallbacks; + BLEAdvertisingArbiter::Request mAdvertisingRequest = {}; +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + PacketBufferHandle c3CharDataBufferHandle; +#endif + + void DriveBLEState(void); + CHIP_ERROR PrepareAdvertisingRequest(); + CHIP_ERROR StartAdvertising(void); + CHIP_ERROR StopAdvertising(void); + CHIP_ERROR HandleGAPConnect(const ChipDeviceEvent * event); + CHIP_ERROR HandleGAPDisconnect(const ChipDeviceEvent * event); + CHIP_ERROR HandleRXCharWrite(const ChipDeviceEvent * event); + CHIP_ERROR HandleTXCharCCCDWrite(const ChipDeviceEvent * event); + CHIP_ERROR HandleTXCharComplete(const ChipDeviceEvent * event); +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + CHIP_ERROR PrepareC3CharData(); +#endif + bool IsSubscribed(bt_conn * conn); + bool SetSubscribed(bt_conn * conn); + bool UnsetSubscribed(bt_conn * conn); + uint32_t GetAdvertisingInterval(); + + static void DriveBLEState(intptr_t arg); + + // Below callbacks run from the system workqueue context and have a limited stack capacity. + static void HandleTXIndicated(bt_conn * conn, bt_gatt_indicate_params * attr, uint8_t err); + static void HandleConnect(bt_conn * conn, uint8_t err); + static void HandleDisconnect(bt_conn * conn, uint8_t reason); + static void HandleBLEAdvertisementIntervalChange(System::Layer * layer, void * param); + + // ===== Members for internal use by the following friends. + + friend BLEManager & BLEMgr(void); + friend BLEManagerImpl & BLEMgrImpl(void); + + static BLEManagerImpl sInstance; + +public: + // Below callbacks are public in order to be visible from the global scope. + static ssize_t HandleRXWrite(bt_conn * conn, const bt_gatt_attr * attr, const void * buf, uint16_t len, uint16_t offset, + uint8_t flags); + static ssize_t HandleTXCCCWrite(bt_conn * conn, const bt_gatt_attr * attr, uint16_t value); + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + static ssize_t HandleC3Read(struct bt_conn * conn, const struct bt_gatt_attr * attr, void * buf, uint16_t len, uint16_t offset); +#endif +}; + +/** + * Returns a reference to the public interface of the BLEManager singleton object. + * + * Internal components should use this to access features of the BLEManager object + * that are common to all platforms. + */ +inline BLEManager & BLEMgr(void) +{ + return BLEManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the BLEManager singleton object. + * + * Internal components can use this to gain access to features of the BLEManager + * that are specific to the Zephyr platforms. + */ +inline BLEManagerImpl & BLEMgrImpl(void) +{ + return BLEManagerImpl::sInstance; +} + +inline BleLayer * BLEManagerImpl::_GetBleLayer() +{ + return this; +} + +inline bool BLEManagerImpl::_IsAdvertisingEnabled(void) +{ + return mFlags.Has(Flags::kAdvertisingEnabled); +} + +inline bool BLEManagerImpl::_IsAdvertising(void) +{ + return mFlags.Has(Flags::kAdvertising); +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/nxp/rt/rw61x/BUILD.gn b/src/platform/nxp/rt/rw61x/BUILD.gn index 0e3558b8bf916a..7337f896c8ddcc 100644 --- a/src/platform/nxp/rt/rw61x/BUILD.gn +++ b/src/platform/nxp/rt/rw61x/BUILD.gn @@ -83,20 +83,20 @@ static_library("nxp_platform") { sources += [ "../../common/NXPConfigKS.cpp" ] } - public_deps = [ "${chip_root}/src/platform:platform_base" ] - - deps += [ "${chip_root}/src/platform/logging:headers" ] - if (chip_enable_ble) { sources += [ # Adding random file which defines the function sys_csrand_get which is called by BLEManagerImpl from Zephyr "${nxp_sdk_build_root}/${nxp_sdk_name}/sdk_hook/zephyr/random/random.cpp", - "../../../Zephyr/BLEAdvertisingArbiter.cpp", - "../../../Zephyr/BLEManagerImpl.cpp", + "../../common/ble_zephyr/BLEAdvertisingArbiter.cpp", + "../../common/ble_zephyr/BLEManagerImpl.cpp", "../../common/ble_zephyr/BLEManagerImpl.h", ] } + public_deps = [ "${chip_root}/src/platform:platform_base" ] + + deps += [ "${chip_root}/src/platform/logging:headers" ] + # define CHIP_PLAT_NVM_SUPPORT - See NXPConfig.cpp for definition if (rt_nvm_component == "nvm_fwk") { defines += [ "CHIP_PLAT_NVM_SUPPORT=1" ] 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/platform/tests/BUILD.gn b/src/platform/tests/BUILD.gn index bf4c2ee6ff90f4..ba092e2f7ee5dd 100644 --- a/src/platform/tests/BUILD.gn +++ b/src/platform/tests/BUILD.gn @@ -38,6 +38,7 @@ if (chip_device_platform != "none" && chip_device_platform != "fake") { } public_deps = [ + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/platform", diff --git a/src/platform/tests/TestCHIPoBLEStackMgr.cpp b/src/platform/tests/TestCHIPoBLEStackMgr.cpp index 2ec392849c7eca..fb39b6b6462568 100644 --- a/src/platform/tests/TestCHIPoBLEStackMgr.cpp +++ b/src/platform/tests/TestCHIPoBLEStackMgr.cpp @@ -16,14 +16,14 @@ */ #include "platform/internal/CHIPDeviceLayerInternal.h" -#include -#include + +#include + +#include #include #include -#include - -#include "platform/PlatformManager.h" -#include "platform/internal/BLEManager.h" +#include +#include void EventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t) { diff --git a/src/platform/tests/TestCHIPoBLEStackMgrDriver.cpp b/src/platform/tests/TestCHIPoBLEStackMgrDriver.cpp index 38e3f23a10b59c..7e56479513fbf7 100644 --- a/src/platform/tests/TestCHIPoBLEStackMgrDriver.cpp +++ b/src/platform/tests/TestCHIPoBLEStackMgrDriver.cpp @@ -15,10 +15,12 @@ * limitations under the License. */ -#include -#include #include +#include + +#include + int main(int argc, char * argv[]) { testing::InitGoogleTest(&argc, argv); diff --git a/src/platform/tests/TestConfigurationMgr.cpp b/src/platform/tests/TestConfigurationMgr.cpp index ad60d44583250f..d40c600c5d03f3 100644 --- a/src/platform/tests/TestConfigurationMgr.cpp +++ b/src/platform/tests/TestConfigurationMgr.cpp @@ -28,10 +28,11 @@ #include #include -#include +#include + +#include #include #include - #include #include #include diff --git a/src/platform/tests/TestConnectivityMgr.cpp b/src/platform/tests/TestConnectivityMgr.cpp index 0699f971dfc493..55a7e97f7c24f6 100644 --- a/src/platform/tests/TestConnectivityMgr.cpp +++ b/src/platform/tests/TestConnectivityMgr.cpp @@ -28,11 +28,11 @@ #include #include +#include + +#include #include #include - -#include - #include #include diff --git a/src/platform/tests/TestDnssd.cpp b/src/platform/tests/TestDnssd.cpp index 43a3d62d61dc9a..5aa7565274f657 100644 --- a/src/platform/tests/TestDnssd.cpp +++ b/src/platform/tests/TestDnssd.cpp @@ -17,12 +17,13 @@ #include -#include +#include #include "lib/dnssd/platform/Dnssd.h" #include "platform/CHIPDeviceLayer.h" #include "platform/ConnectivityManager.h" #include "platform/PlatformManager.h" +#include #include #include #include diff --git a/src/platform/tests/TestKeyValueStoreMgr.cpp b/src/platform/tests/TestKeyValueStoreMgr.cpp index 49ddcb99752492..0429182e0c40c8 100644 --- a/src/platform/tests/TestKeyValueStoreMgr.cpp +++ b/src/platform/tests/TestKeyValueStoreMgr.cpp @@ -22,10 +22,10 @@ * */ -#include +#include +#include #include - #include #include diff --git a/src/platform/tests/TestPlatformMgr.cpp b/src/platform/tests/TestPlatformMgr.cpp index 96c989aa7455b2..51ec10bf8766dc 100644 --- a/src/platform/tests/TestPlatformMgr.cpp +++ b/src/platform/tests/TestPlatformMgr.cpp @@ -30,7 +30,9 @@ #include -#include +#include + +#include #include #include #include diff --git a/src/platform/tests/TestPlatformTime.cpp b/src/platform/tests/TestPlatformTime.cpp index 54cf60202b4440..ad7a59052b21f4 100644 --- a/src/platform/tests/TestPlatformTime.cpp +++ b/src/platform/tests/TestPlatformTime.cpp @@ -28,7 +28,9 @@ #include #include -#include +#include + +#include #include #include #include diff --git a/src/platform/tests/TestThreadStackMgr.cpp b/src/platform/tests/TestThreadStackMgr.cpp index 143de88587ccd5..ee381280529250 100644 --- a/src/platform/tests/TestThreadStackMgr.cpp +++ b/src/platform/tests/TestThreadStackMgr.cpp @@ -18,7 +18,9 @@ #include #include -#include +#include + +#include #include #include diff --git a/src/protocols/bdx/tests/BUILD.gn b/src/protocols/bdx/tests/BUILD.gn index 055301b3432916..25c8f2b8462995 100644 --- a/src/protocols/bdx/tests/BUILD.gn +++ b/src/protocols/bdx/tests/BUILD.gn @@ -28,6 +28,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/protocols/bdx", ] diff --git a/src/protocols/bdx/tests/TestBdxMessages.cpp b/src/protocols/bdx/tests/TestBdxMessages.cpp index 6475cbd89c14c2..2bed80ae8aecf4 100644 --- a/src/protocols/bdx/tests/TestBdxMessages.cpp +++ b/src/protocols/bdx/tests/TestBdxMessages.cpp @@ -1,12 +1,12 @@ -#include +#include -#include +#include +#include #include #include #include - -#include +#include using namespace chip; using namespace chip::bdx; diff --git a/src/protocols/bdx/tests/TestBdxTransferSession.cpp b/src/protocols/bdx/tests/TestBdxTransferSession.cpp index a3a76df6bddf67..8fcc4fab312f26 100644 --- a/src/protocols/bdx/tests/TestBdxTransferSession.cpp +++ b/src/protocols/bdx/tests/TestBdxTransferSession.cpp @@ -1,15 +1,15 @@ -#include -#include -#include - #include -#include +#include +#include #include #include #include #include +#include +#include +#include #include #include #include diff --git a/src/protocols/bdx/tests/TestBdxUri.cpp b/src/protocols/bdx/tests/TestBdxUri.cpp index e94b88ec0d9f21..60125695809dc7 100644 --- a/src/protocols/bdx/tests/TestBdxUri.cpp +++ b/src/protocols/bdx/tests/TestBdxUri.cpp @@ -15,10 +15,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include #include -#include + +#include + +#include +#include using namespace ::chip; diff --git a/src/protocols/interaction_model/tests/BUILD.gn b/src/protocols/interaction_model/tests/BUILD.gn index 875146e3958ec6..b3a5c3c157244a 100644 --- a/src/protocols/interaction_model/tests/BUILD.gn +++ b/src/protocols/interaction_model/tests/BUILD.gn @@ -24,6 +24,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/protocols/interaction_model", ] diff --git a/src/protocols/interaction_model/tests/TestStatusCode.cpp b/src/protocols/interaction_model/tests/TestStatusCode.cpp index 3183d68e2e5f22..83f2dc3525c846 100644 --- a/src/protocols/interaction_model/tests/TestStatusCode.cpp +++ b/src/protocols/interaction_model/tests/TestStatusCode.cpp @@ -18,8 +18,10 @@ #include -#include +#include + #include +#include #include using namespace ::chip; 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/BUILD.gn b/src/protocols/secure_channel/tests/BUILD.gn index 0760998e818422..a5e6d73455eaea 100644 --- a/src/protocols/secure_channel/tests/BUILD.gn +++ b/src/protocols/secure_channel/tests/BUILD.gn @@ -28,6 +28,7 @@ chip_test_suite("tests") { "${chip_root}/src/credentials/tests:cert_test_vectors", "${chip_root}/src/crypto/tests:tests.lib", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/lib/support:testing", diff --git a/src/protocols/secure_channel/tests/TestCASESession.cpp b/src/protocols/secure_channel/tests/TestCASESession.cpp index 24aaffce0dbcb4..67b4cdd7d69faf 100644 --- a/src/protocols/secure_channel/tests/TestCASESession.cpp +++ b/src/protocols/secure_channel/tests/TestCASESession.cpp @@ -21,16 +21,20 @@ * This file implements unit tests for the CASESession implementation. */ +#include + +#include + #include #include #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -39,7 +43,6 @@ #include #include #include -#include #include "credentials/tests/CHIPCert_test_vectors.h" @@ -56,7 +59,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 +73,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/TestCheckInCounter.cpp b/src/protocols/secure_channel/tests/TestCheckInCounter.cpp index 57dbd4b3496cdd..f3d85d98815638 100644 --- a/src/protocols/secure_channel/tests/TestCheckInCounter.cpp +++ b/src/protocols/secure_channel/tests/TestCheckInCounter.cpp @@ -16,11 +16,14 @@ * limitations under the License. */ -#include +#include + +#include + #include +#include #include #include -#include using namespace chip; using namespace chip::Protocols::SecureChannel; diff --git a/src/protocols/secure_channel/tests/TestCheckinMsg.cpp b/src/protocols/secure_channel/tests/TestCheckinMsg.cpp index d5885f3a6d06bb..23f3b2f2d68ca4 100644 --- a/src/protocols/secure_channel/tests/TestCheckinMsg.cpp +++ b/src/protocols/secure_channel/tests/TestCheckinMsg.cpp @@ -16,9 +16,11 @@ * limitations under the License. */ +#include + #include #include -#include +#include #include #include #include diff --git a/src/protocols/secure_channel/tests/TestDefaultSessionResumptionStorage.cpp b/src/protocols/secure_channel/tests/TestDefaultSessionResumptionStorage.cpp index 59dcf3080a8ec3..70b841aec80581 100644 --- a/src/protocols/secure_channel/tests/TestDefaultSessionResumptionStorage.cpp +++ b/src/protocols/secure_channel/tests/TestDefaultSessionResumptionStorage.cpp @@ -15,7 +15,9 @@ * limitations under the License. */ -#include +#include + +#include #include #include diff --git a/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp b/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp index 41b6539ecf0773..838e14cf6bd302 100644 --- a/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp +++ b/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp @@ -21,9 +21,14 @@ * This file implements unit tests for the MessageCounterManager implementation. */ +#include + +#include +#include + #include +#include #include - #include #include #include @@ -34,11 +39,6 @@ #include #include -#include -#include - -#include - namespace { using namespace chip; @@ -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..bf120b20823ceb 100644 --- a/src/protocols/secure_channel/tests/TestPASESession.cpp +++ b/src/protocols/secure_channel/tests/TestPASESession.cpp @@ -22,11 +22,13 @@ */ #include -#include + +#include #include #include #include +#include #include #include #include @@ -84,21 +86,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/protocols/secure_channel/tests/TestPairingSession.cpp b/src/protocols/secure_channel/tests/TestPairingSession.cpp index 5a12f61fc5c69e..b8d29c1c1742b8 100644 --- a/src/protocols/secure_channel/tests/TestPairingSession.cpp +++ b/src/protocols/secure_channel/tests/TestPairingSession.cpp @@ -22,14 +22,15 @@ */ #include -#include +#include + +#include #include +#include #include - #include #include -#include #include #include diff --git a/src/protocols/secure_channel/tests/TestSimpleSessionResumptionStorage.cpp b/src/protocols/secure_channel/tests/TestSimpleSessionResumptionStorage.cpp index ee107f695542a9..c90ec3550e0068 100644 --- a/src/protocols/secure_channel/tests/TestSimpleSessionResumptionStorage.cpp +++ b/src/protocols/secure_channel/tests/TestSimpleSessionResumptionStorage.cpp @@ -15,8 +15,9 @@ * limitations under the License. */ -#include +#include +#include #include #include diff --git a/src/protocols/secure_channel/tests/TestStatusReport.cpp b/src/protocols/secure_channel/tests/TestStatusReport.cpp index 65bc639dcca7c3..a76376f6925320 100644 --- a/src/protocols/secure_channel/tests/TestStatusReport.cpp +++ b/src/protocols/secure_channel/tests/TestStatusReport.cpp @@ -16,17 +16,17 @@ * limitations under the License. */ +#include + +#include #include #include #include - #include #include #include #include -#include - using namespace chip; using namespace chip::Protocols; using namespace chip::Protocols::SecureChannel; diff --git a/src/protocols/user_directed_commissioning/tests/BUILD.gn b/src/protocols/user_directed_commissioning/tests/BUILD.gn index ee67f0492ece92..c7e8f711bd0a5c 100644 --- a/src/protocols/user_directed_commissioning/tests/BUILD.gn +++ b/src/protocols/user_directed_commissioning/tests/BUILD.gn @@ -22,6 +22,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/protocols", ] diff --git a/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp b/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp index 9dd05083de6ced..d6115a73913778 100644 --- a/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp +++ b/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp @@ -1,8 +1,9 @@ #include -#include +#include #include +#include #include #include #include diff --git a/src/python_testing/TC_ACE_1_2.py b/src/python_testing/TC_ACE_1_2.py index 2c6f07a217183a..9bd26523f3cbba 100644 --- a/src/python_testing/TC_ACE_1_2.py +++ b/src/python_testing/TC_ACE_1_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import logging import queue diff --git a/src/python_testing/TC_ACE_1_3.py b/src/python_testing/TC_ACE_1_3.py index 150683357e1e9c..3c64171571eb95 100644 --- a/src/python_testing/TC_ACE_1_3.py +++ b/src/python_testing/TC_ACE_1_3.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_ACE_1_4.py b/src/python_testing/TC_ACE_1_4.py index 31cc7cb0c15a3a..f6f04e3508860b 100644 --- a/src/python_testing/TC_ACE_1_4.py +++ b/src/python_testing/TC_ACE_1_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --int-arg PIXIT.ACE.APPENDPOINT:1 PIXIT.ACE.APPDEVTYPEID:0x0100 --string-arg PIXIT.ACE.APPCLUSTER:OnOff PIXIT.ACE.APPATTRIBUTE:OnOff --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import sys diff --git a/src/python_testing/TC_ACE_1_5.py b/src/python_testing/TC_ACE_1_5.py index e88a040e31b983..00bd343d461cb3 100644 --- a/src/python_testing/TC_ACE_1_5.py +++ b/src/python_testing/TC_ACE_1_5.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_AccessChecker.py b/src/python_testing/TC_AccessChecker.py index f2bbf36330ec6a..36c643407937e2 100644 --- a/src/python_testing/TC_AccessChecker.py +++ b/src/python_testing/TC_AccessChecker.py @@ -1,9 +1,14 @@ +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import logging from copy import deepcopy diff --git a/src/python_testing/TC_CGEN_2_4.py b/src/python_testing/TC_CGEN_2_4.py index ef22360dac341d..7d9d075dc16cb9 100644 --- a/src/python_testing/TC_CGEN_2_4.py +++ b/src/python_testing/TC_CGEN_2_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import logging import random diff --git a/src/python_testing/TC_DA_1_2.py b/src/python_testing/TC_DA_1_2.py index f324a2d3571c77..30a5285a4a4b68 100644 --- a/src/python_testing/TC_DA_1_2.py +++ b/src/python_testing/TC_DA_1_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import os import random diff --git a/src/python_testing/TC_DA_1_5.py b/src/python_testing/TC_DA_1_5.py index 7e3bd92cda26e9..d37f236a9fccf4 100644 --- a/src/python_testing/TC_DA_1_5.py +++ b/src/python_testing/TC_DA_1_5.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import random diff --git a/src/python_testing/TC_DA_1_7.py b/src/python_testing/TC_DA_1_7.py index 9e25bdee88fa6a..8338cf4713a2a5 100644 --- a/src/python_testing/TC_DA_1_7.py +++ b/src/python_testing/TC_DA_1_7.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --bool-arg allow_sdk_dac:true --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging from glob import glob diff --git a/src/python_testing/TC_DGGEN_2_4.py b/src/python_testing/TC_DGGEN_2_4.py index f68cefa260c76f..ee80d927a9b6c1 100644 --- a/src/python_testing/TC_DGGEN_2_4.py +++ b/src/python_testing/TC_DGGEN_2_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import asyncio import logging diff --git a/src/python_testing/TC_DRLK_2_12.py b/src/python_testing/TC_DRLK_2_12.py index 81c2271f52c0dd..4578aa01cd2ba0 100644 --- a/src/python_testing/TC_DRLK_2_12.py +++ b/src/python_testing/TC_DRLK_2_12.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_LOCK_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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === from drlk_2_x_common import DRLK_COMMON from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_DRLK_2_2.py b/src/python_testing/TC_DRLK_2_2.py index fcb6c1068b26eb..e7f3e6fa8e421e 100644 --- a/src/python_testing/TC_DRLK_2_2.py +++ b/src/python_testing/TC_DRLK_2_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_LOCK_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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === from drlk_2_x_common import DRLK_COMMON from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_DRLK_2_3.py b/src/python_testing/TC_DRLK_2_3.py index e30ac7b2a02635..8c6f40f19c5449 100644 --- a/src/python_testing/TC_DRLK_2_3.py +++ b/src/python_testing/TC_DRLK_2_3.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_LOCK_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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === from drlk_2_x_common import DRLK_COMMON from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_DeviceBasicComposition.py b/src/python_testing/TC_DeviceBasicComposition.py index cff612b33f6497..7af7b865542e42 100644 --- a/src/python_testing/TC_DeviceBasicComposition.py +++ b/src/python_testing/TC_DeviceBasicComposition.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --manual-code 10054912339 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging from dataclasses import dataclass diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index ec28db53693c96..851921df60f0a4 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_LOCK_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 --manual-code 10054912339 --bool-arg ignore_in_progress:True allow_provisional:True --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --tests test_TC_IDM_10_2 +# === END CI TEST ARGUMENTS === from typing import Callable @@ -119,12 +124,12 @@ def record_warning(location, problem): record_error(location=location, problem=f'Unknown feature with mask 0x{f:02x}') continue xml_feature = self.xml_clusters[cluster_id].features[f] - conformance_decision = xml_feature.conformance(feature_map, attribute_list, all_command_list) - if not conformance_allowed(conformance_decision, allow_provisional): + conformance_decision_with_choice = xml_feature.conformance(feature_map, attribute_list, all_command_list) + if not conformance_allowed(conformance_decision_with_choice, allow_provisional): record_error(location=location, problem=f'Disallowed feature with mask 0x{f:02x}') for feature_mask, xml_feature in self.xml_clusters[cluster_id].features.items(): - conformance_decision = xml_feature.conformance(feature_map, attribute_list, all_command_list) - if conformance_decision == ConformanceDecision.MANDATORY and feature_mask not in feature_masks: + conformance_decision_with_choice = xml_feature.conformance(feature_map, attribute_list, all_command_list) + if conformance_decision_with_choice.decision == ConformanceDecision.MANDATORY and feature_mask not in feature_masks: record_error( location=location, problem=f'Required feature with mask 0x{f:02x} is not present in feature map. {conformance_str(xml_feature.conformance, feature_map, self.xml_clusters[cluster_id].features)}') @@ -140,16 +145,16 @@ def record_warning(location, problem): record_error(location=location, problem='Standard attribute found on device, but not in spec') continue xml_attribute = self.xml_clusters[cluster_id].attributes[attribute_id] - conformance_decision = xml_attribute.conformance(feature_map, attribute_list, all_command_list) - if not conformance_allowed(conformance_decision, allow_provisional): + conformance_decision_with_choice = xml_attribute.conformance(feature_map, attribute_list, all_command_list) + if not conformance_allowed(conformance_decision_with_choice, allow_provisional): location = AttributePathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, attribute_id=attribute_id) record_error( location=location, problem=f'Attribute 0x{attribute_id:02x} is included, but is disallowed by conformance. {conformance_str(xml_attribute.conformance, feature_map, self.xml_clusters[cluster_id].features)}') for attribute_id, xml_attribute in self.xml_clusters[cluster_id].attributes.items(): if cluster_id in ignore_attributes and attribute_id in ignore_attributes[cluster_id]: continue - conformance_decision = xml_attribute.conformance(feature_map, attribute_list, all_command_list) - if conformance_decision == ConformanceDecision.MANDATORY and attribute_id not in cluster.keys(): + conformance_decision_with_choice = xml_attribute.conformance(feature_map, attribute_list, all_command_list) + if conformance_decision_with_choice.decision == ConformanceDecision.MANDATORY and attribute_id not in cluster.keys(): location = AttributePathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, attribute_id=attribute_id) record_error( location=location, problem=f'Attribute 0x{attribute_id:02x} is required, but is not present on the DUT. {conformance_str(xml_attribute.conformance, feature_map, self.xml_clusters[cluster_id].features)}') @@ -168,13 +173,13 @@ def check_spec_conformance_for_commands(command_type: CommandType): record_error(location=location, problem='Standard command found on device, but not in spec') continue xml_command = xml_commands_dict[command_id] - conformance_decision = xml_command.conformance(feature_map, attribute_list, all_command_list) - if not conformance_allowed(conformance_decision, allow_provisional): + conformance_decision_with_choice = xml_command.conformance(feature_map, attribute_list, all_command_list) + if not conformance_allowed(conformance_decision_with_choice, allow_provisional): record_error( location=location, problem=f'Command 0x{command_id:02x} is included, but disallowed by conformance. {conformance_str(xml_command.conformance, feature_map, self.xml_clusters[cluster_id].features)}') for command_id, xml_command in xml_commands_dict.items(): - conformance_decision = xml_command.conformance(feature_map, attribute_list, all_command_list) - if conformance_decision == ConformanceDecision.MANDATORY and command_id not in command_list: + conformance_decision_with_choice = xml_command.conformance(feature_map, attribute_list, all_command_list) + if conformance_decision_with_choice.decision == ConformanceDecision.MANDATORY and command_id not in command_list: location = CommandPathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, command_id=command_id) record_error( location=location, problem=f'Command 0x{command_id:02x} is required, but is not present on the DUT. {conformance_str(xml_command.conformance, feature_map, self.xml_clusters[cluster_id].features)}') diff --git a/src/python_testing/TC_EEM_2_1.py b/src/python_testing/TC_EEM_2_1.py index 51e01a1e4b3980..d5a2c0751145d1 100644 --- a/src/python_testing/TC_EEM_2_1.py +++ b/src/python_testing/TC_EEM_2_1.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_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 --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging @@ -44,13 +49,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 +76,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..e8094a0d834ca3 100644 --- a/src/python_testing/TC_EEM_2_2.py +++ b/src/python_testing/TC_EEM_2_2.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_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 --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import time @@ -40,13 +45,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 +80,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..2364f0d012530c 100644 --- a/src/python_testing/TC_EEM_2_3.py +++ b/src/python_testing/TC_EEM_2_3.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_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 --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import time @@ -40,13 +45,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 +80,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..b3f052bc968411 100644 --- a/src/python_testing/TC_EEM_2_4.py +++ b/src/python_testing/TC_EEM_2_4.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_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 --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import time @@ -40,13 +45,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 +80,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..f7fd34a0d05eca 100644 --- a/src/python_testing/TC_EEM_2_5.py +++ b/src/python_testing/TC_EEM_2_5.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_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 --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import time @@ -40,13 +45,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 +80,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..833375e0fb7523 100644 --- a/src/python_testing/TC_EEVSE_2_2.py +++ b/src/python_testing/TC_EEVSE_2_2.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_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 --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import time @@ -47,51 +52,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 +175,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 +192,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 +222,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 +247,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 +268,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 +282,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 +304,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 +351,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 +385,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..3b2db653e86b63 100644 --- a/src/python_testing/TC_EEVSE_2_4.py +++ b/src/python_testing/TC_EEVSE_2_4.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_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 --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import time @@ -45,30 +50,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 +131,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 +150,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 +161,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 +177,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 +193,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 +209,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..89ee987ace2f66 100644 --- a/src/python_testing/TC_EEVSE_2_5.py +++ b/src/python_testing/TC_EEVSE_2_5.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_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 --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging @@ -45,24 +50,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..81f0406a182f49 100644 --- a/src/python_testing/TC_EPM_2_1.py +++ b/src/python_testing/TC_EPM_2_1.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_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 --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging @@ -46,26 +51,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 +136,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 +157,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 +231,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 +243,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..89c49928b3baa1 100644 --- a/src/python_testing/TC_EPM_2_2.py +++ b/src/python_testing/TC_EPM_2_2.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_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 --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import time @@ -44,17 +49,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 +91,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_FAN_3_1.py b/src/python_testing/TC_FAN_3_1.py index f16eaf35f6c4a2..9e4477e9a258fa 100644 --- a/src/python_testing/TC_FAN_3_1.py +++ b/src/python_testing/TC_FAN_3_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import logging import time diff --git a/src/python_testing/TC_FAN_3_2.py b/src/python_testing/TC_FAN_3_2.py index 85a733a14c4033..e38706313db50d 100644 --- a/src/python_testing/TC_FAN_3_2.py +++ b/src/python_testing/TC_FAN_3_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import logging import time diff --git a/src/python_testing/TC_FAN_3_3.py b/src/python_testing/TC_FAN_3_3.py index 0ef571dffb0aa1..a70c457aed25d3 100644 --- a/src/python_testing/TC_FAN_3_3.py +++ b/src/python_testing/TC_FAN_3_3.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_FAN_3_4.py b/src/python_testing/TC_FAN_3_4.py index 1d7e7c8c9f81c5..95a2240c4eae5c 100644 --- a/src/python_testing/TC_FAN_3_4.py +++ b/src/python_testing/TC_FAN_3_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_FAN_3_5.py b/src/python_testing/TC_FAN_3_5.py index 67a15919db8a6c..a80e4b15aa91eb 100644 --- a/src/python_testing/TC_FAN_3_5.py +++ b/src/python_testing/TC_FAN_3_5.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import logging import time diff --git a/src/python_testing/TC_ICDM_2_1.py b/src/python_testing/TC_ICDM_2_1.py index 44fde90aee7813..ac20cf2c001fb0 100644 --- a/src/python_testing/TC_ICDM_2_1.py +++ b/src/python_testing/TC_ICDM_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${LIT_ICD_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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import re diff --git a/src/python_testing/TC_ICDM_3_1.py b/src/python_testing/TC_ICDM_3_1.py index f5a37cd763c7af..938479a9147f5f 100644 --- a/src/python_testing/TC_ICDM_3_1.py +++ b/src/python_testing/TC_ICDM_3_1.py @@ -16,12 +16,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${LIT_ICD_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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import os diff --git a/src/python_testing/TC_ICDManagementCluster.py b/src/python_testing/TC_ICDManagementCluster.py index 6db1863e45bc1e..6030830cacded2 100644 --- a/src/python_testing/TC_ICDManagementCluster.py +++ b/src/python_testing/TC_ICDManagementCluster.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${LIT_ICD_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 --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import ctypes from enum import IntEnum diff --git a/src/python_testing/TC_IDM_1_2.py b/src/python_testing/TC_IDM_1_2.py index c91cef571d952f..d5985c8ae967f1 100644 --- a/src/python_testing/TC_IDM_1_2.py +++ b/src/python_testing/TC_IDM_1_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import inspect import logging diff --git a/src/python_testing/TC_IDM_1_4.py b/src/python_testing/TC_IDM_1_4.py index 07d3cde29ba326..fcfb5915ed136a 100644 --- a/src/python_testing/TC_IDM_1_4.py +++ b/src/python_testing/TC_IDM_1_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --hex-arg PIXIT.DGGEN.TEST_EVENT_TRIGGER_KEY:000102030405060708090a0b0c0d0e0f --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 +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_IDM_4_2.py b/src/python_testing/TC_IDM_4_2.py index 60016ba4dcf20a..8cd84011a4fdfe 100644 --- a/src/python_testing/TC_IDM_4_2.py +++ b/src/python_testing/TC_IDM_4_2.py @@ -15,16 +15,29 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# 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 +# === END CI TEST ARGUMENTS === + 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 +58,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 +98,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 +128,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 +150,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 +171,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 +179,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 +192,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 +209,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 +264,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 +301,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 +321,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 +344,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 +355,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 +370,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 +379,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 +413,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 +423,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 +442,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 +452,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 +478,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() - # 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.") + # Elapsed time between attribute subscription and write update + t_elapsed_sec = t_update_sec - t_report_sec + + # 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 +605,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 +668,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_MWOCTRL_2_1.py b/src/python_testing/TC_MWOCTRL_2_1.py index 225a4569b345f0..0de3bee72ec12f 100644 --- a/src/python_testing/TC_MWOCTRL_2_1.py +++ b/src/python_testing/TC_MWOCTRL_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_MICROWAVE_OVEN_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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from chip.interaction_model import InteractionModelError, Status diff --git a/src/python_testing/TC_MWOCTRL_2_2.py b/src/python_testing/TC_MWOCTRL_2_2.py index 54cf7a90463831..0edc2ac6616fde 100644 --- a/src/python_testing/TC_MWOCTRL_2_2.py +++ b/src/python_testing/TC_MWOCTRL_2_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_MICROWAVE_OVEN_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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_MWOCTRL_2_4.py b/src/python_testing/TC_MWOCTRL_2_4.py index 136f9f882ab20e..fce17c4175d6c5 100644 --- a/src/python_testing/TC_MWOCTRL_2_4.py +++ b/src/python_testing/TC_MWOCTRL_2_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_MICROWAVE_OVEN_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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_MWOM_1_2.py b/src/python_testing/TC_MWOM_1_2.py index c92f8d5c5804fc..7d29c3f43eba35 100644 --- a/src/python_testing/TC_MWOM_1_2.py +++ b/src/python_testing/TC_MWOM_1_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_MICROWAVE_OVEN_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 +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_OPCREDS_3_1.py b/src/python_testing/TC_OPCREDS_3_1.py index b29fb84999cc41..dd92fd7a2f88b9 100644 --- a/src/python_testing/TC_OPCREDS_3_1.py +++ b/src/python_testing/TC_OPCREDS_3_1.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import copy import logging import random diff --git a/src/python_testing/TC_OPCREDS_3_2.py b/src/python_testing/TC_OPCREDS_3_2.py index 384540c249e7ca..3eab07bc9dae06 100644 --- a/src/python_testing/TC_OPCREDS_3_2.py +++ b/src/python_testing/TC_OPCREDS_3_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from chip.tlv import TLVReader diff --git a/src/python_testing/TC_OPSTATE_2_1.py b/src/python_testing/TC_OPSTATE_2_1.py index ef9afa0a14b741..c3be8a438c14b8 100644 --- a/src/python_testing/TC_OPSTATE_2_1.py +++ b/src/python_testing/TC_OPSTATE_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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: --endpoint 1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_OPSTATE_2_2.py b/src/python_testing/TC_OPSTATE_2_2.py index e8b5286af5ee5c..09e4c6591813e4 100644 --- a/src/python_testing/TC_OPSTATE_2_2.py +++ b/src/python_testing/TC_OPSTATE_2_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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: --endpoint 1 --int-arg PIXIT.WAITTIME.COUNTDOWN:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_OPSTATE_2_3.py b/src/python_testing/TC_OPSTATE_2_3.py index c8abb6bc88a38b..b9a62b275c52aa 100644 --- a/src/python_testing/TC_OPSTATE_2_3.py +++ b/src/python_testing/TC_OPSTATE_2_3.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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: --endpoint 1 --int-arg PIXIT.WAITTIME.COUNTDOWN:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters diff --git a/src/python_testing/TC_OPSTATE_2_4.py b/src/python_testing/TC_OPSTATE_2_4.py index 21e18fd10cd8a5..512802467f8f2c 100644 --- a/src/python_testing/TC_OPSTATE_2_4.py +++ b/src/python_testing/TC_OPSTATE_2_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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: --endpoint 1 --int-arg PIXIT.OPSTATE.ErrorEventGen:1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters diff --git a/src/python_testing/TC_OPSTATE_2_5.py b/src/python_testing/TC_OPSTATE_2_5.py index fe42a59ffb0b8f..ad79765e8890fd 100644 --- a/src/python_testing/TC_OPSTATE_2_5.py +++ b/src/python_testing/TC_OPSTATE_2_5.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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: --endpoint 1 --int-arg PIXIT.WAITTIME.REBOOT:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters diff --git a/src/python_testing/TC_OVENOPSTATE_2_1.py b/src/python_testing/TC_OVENOPSTATE_2_1.py index 56d7fe2087818a..1d1a2890802e33 100644 --- a/src/python_testing/TC_OVENOPSTATE_2_1.py +++ b/src/python_testing/TC_OVENOPSTATE_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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: --endpoint 1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters diff --git a/src/python_testing/TC_OVENOPSTATE_2_2.py b/src/python_testing/TC_OVENOPSTATE_2_2.py index 158bae59260ff3..254464eaa661f9 100644 --- a/src/python_testing/TC_OVENOPSTATE_2_2.py +++ b/src/python_testing/TC_OVENOPSTATE_2_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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: --endpoint 1 --int-arg PIXIT.WAITTIME.COUNTDOWN:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_OVENOPSTATE_2_3.py b/src/python_testing/TC_OVENOPSTATE_2_3.py index 1f882b3b4ba987..77d4358788afad 100644 --- a/src/python_testing/TC_OVENOPSTATE_2_3.py +++ b/src/python_testing/TC_OVENOPSTATE_2_3.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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: --endpoint 1 --int-arg PIXIT.WAITTIME.COUNTDOWN:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_OVENOPSTATE_2_4.py b/src/python_testing/TC_OVENOPSTATE_2_4.py index 7fa53e73dd8e5f..70a3a6f0207cee 100644 --- a/src/python_testing/TC_OVENOPSTATE_2_4.py +++ b/src/python_testing/TC_OVENOPSTATE_2_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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: --endpoint 1 --int-arg PIXIT.OVENOPSTATE.ErrorEventGen:1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_OVENOPSTATE_2_5.py b/src/python_testing/TC_OVENOPSTATE_2_5.py index 0982ec4f2ff64c..39edb670ff6f5c 100644 --- a/src/python_testing/TC_OVENOPSTATE_2_5.py +++ b/src/python_testing/TC_OVENOPSTATE_2_5.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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: --endpoint 1 --int-arg PIXIT.WAITTIME.REBOOT:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters diff --git a/src/python_testing/TC_PWRTL_2_1.py b/src/python_testing/TC_PWRTL_2_1.py index 93e0e946fe19ea..7216031a9374f4 100644 --- a/src/python_testing/TC_PWRTL_2_1.py +++ b/src/python_testing/TC_PWRTL_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_RR_1_1.py b/src/python_testing/TC_RR_1_1.py index 5e25f2a77ff086..0cb53a4fb491dc 100644 --- a/src/python_testing/TC_RR_1_1.py +++ b/src/python_testing/TC_RR_1_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import asyncio import logging diff --git a/src/python_testing/TC_RVCCLEANM_1_2.py b/src/python_testing/TC_RVCCLEANM_1_2.py index a0b5fa4b6fb551..d1b3018772af23 100644 --- a/src/python_testing/TC_RVCCLEANM_1_2.py +++ b/src/python_testing/TC_RVCCLEANM_1_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_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 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_RVCCLEANM_2_1.py b/src/python_testing/TC_RVCCLEANM_2_1.py index 0a6e72b30cf283..cac18f9601f6ff 100644 --- a/src/python_testing/TC_RVCCLEANM_2_1.py +++ b/src/python_testing/TC_RVCCLEANM_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_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 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --int-arg PIXIT.RVCCLEANM.MODE_CHANGE_FAIL:1 PIXIT.RVCCLEANM.MODE_CHANGE_OK:2 +# === END CI TEST ARGUMENTS === import logging from time import sleep diff --git a/src/python_testing/TC_RVCCLEANM_2_2.py b/src/python_testing/TC_RVCCLEANM_2_2.py index b5f9a108a944f4..8aaae7ff78738f 100644 --- a/src/python_testing/TC_RVCCLEANM_2_2.py +++ b/src/python_testing/TC_RVCCLEANM_2_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_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 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === from time import sleep diff --git a/src/python_testing/TC_RVCOPSTATE_2_1.py b/src/python_testing/TC_RVCOPSTATE_2_1.py index 01d4e0c88c4b13..42a2d02d6fae9c 100644 --- a/src/python_testing/TC_RVCOPSTATE_2_1.py +++ b/src/python_testing/TC_RVCOPSTATE_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_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 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging from time import sleep diff --git a/src/python_testing/TC_RVCOPSTATE_2_3.py b/src/python_testing/TC_RVCOPSTATE_2_3.py index 3b75515f1a23d2..1d915641260d3b 100644 --- a/src/python_testing/TC_RVCOPSTATE_2_3.py +++ b/src/python_testing/TC_RVCOPSTATE_2_3.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_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 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging from time import sleep diff --git a/src/python_testing/TC_RVCOPSTATE_2_4.py b/src/python_testing/TC_RVCOPSTATE_2_4.py index 43b64b9595a172..b680453b06c287 100644 --- a/src/python_testing/TC_RVCOPSTATE_2_4.py +++ b/src/python_testing/TC_RVCOPSTATE_2_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_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 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging from time import sleep diff --git a/src/python_testing/TC_RVCRUNM_1_2.py b/src/python_testing/TC_RVCRUNM_1_2.py index e3e55ddcd07fa4..308e79ab261e23 100644 --- a/src/python_testing/TC_RVCRUNM_1_2.py +++ b/src/python_testing/TC_RVCRUNM_1_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_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 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_RVCRUNM_2_1.py b/src/python_testing/TC_RVCRUNM_2_1.py index ca6986dcbb5840..e98a1840629864 100644 --- a/src/python_testing/TC_RVCRUNM_2_1.py +++ b/src/python_testing/TC_RVCRUNM_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_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 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --int-arg PIXIT.RVCRUNM.MODE_CHANGE_OK:0 PIXIT.RVCRUNM.MODE_CHANGE_FAIL:2 +# === END CI TEST ARGUMENTS === import logging from time import sleep diff --git a/src/python_testing/TC_RVCRUNM_2_2.py b/src/python_testing/TC_RVCRUNM_2_2.py index 5723e1ec2f6fb8..dca866adb9f62e 100644 --- a/src/python_testing/TC_RVCRUNM_2_2.py +++ b/src/python_testing/TC_RVCRUNM_2_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_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 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --int-arg PIXIT.RVCRUNM.MODE_A:1 PIXIT.RVCRUNM.MODE_B:2 +# === END CI TEST ARGUMENTS === from time import sleep diff --git a/src/python_testing/TC_SC_3_6.py b/src/python_testing/TC_SC_3_6.py index 9247cb546e19c6..53353ea85f8bdb 100644 --- a/src/python_testing/TC_SC_3_6.py +++ b/src/python_testing/TC_SC_3_6.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import asyncio diff --git a/src/python_testing/TC_TIMESYNC_2_1.py b/src/python_testing/TC_TIMESYNC_2_1.py index febaea6f1e9d49..cba8ad9570ad2d 100644 --- a/src/python_testing/TC_TIMESYNC_2_1.py +++ b/src/python_testing/TC_TIMESYNC_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import ipaddress from datetime import timedelta diff --git a/src/python_testing/TC_TIMESYNC_2_10.py b/src/python_testing/TC_TIMESYNC_2_10.py index d6b772bcaa1064..c7eb9860b9a8d0 100644 --- a/src/python_testing/TC_TIMESYNC_2_10.py +++ b/src/python_testing/TC_TIMESYNC_2_10.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import queue import time diff --git a/src/python_testing/TC_TIMESYNC_2_11.py b/src/python_testing/TC_TIMESYNC_2_11.py index 7272109525011c..5815baeacadca0 100644 --- a/src/python_testing/TC_TIMESYNC_2_11.py +++ b/src/python_testing/TC_TIMESYNC_2_11.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import queue import time diff --git a/src/python_testing/TC_TIMESYNC_2_12.py b/src/python_testing/TC_TIMESYNC_2_12.py index 1fd05ca352fb38..f530554591202c 100644 --- a/src/python_testing/TC_TIMESYNC_2_12.py +++ b/src/python_testing/TC_TIMESYNC_2_12.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import queue import time diff --git a/src/python_testing/TC_TIMESYNC_2_13.py b/src/python_testing/TC_TIMESYNC_2_13.py index ded6769c7d3828..c667b71edaba55 100644 --- a/src/python_testing/TC_TIMESYNC_2_13.py +++ b/src/python_testing/TC_TIMESYNC_2_13.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import queue import time diff --git a/src/python_testing/TC_TIMESYNC_2_2.py b/src/python_testing/TC_TIMESYNC_2_2.py index 949fac75f2f4f7..83c07355d688d3 100644 --- a/src/python_testing/TC_TIMESYNC_2_2.py +++ b/src/python_testing/TC_TIMESYNC_2_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === from datetime import timedelta diff --git a/src/python_testing/TC_TIMESYNC_2_4.py b/src/python_testing/TC_TIMESYNC_2_4.py index 89c284b21024f6..21d98fd8ca7f9b 100644 --- a/src/python_testing/TC_TIMESYNC_2_4.py +++ b/src/python_testing/TC_TIMESYNC_2_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import typing from datetime import timedelta diff --git a/src/python_testing/TC_TIMESYNC_2_5.py b/src/python_testing/TC_TIMESYNC_2_5.py index ae2b3debbb8569..5c19e3722956d9 100644 --- a/src/python_testing/TC_TIMESYNC_2_5.py +++ b/src/python_testing/TC_TIMESYNC_2_5.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import typing diff --git a/src/python_testing/TC_TIMESYNC_2_6.py b/src/python_testing/TC_TIMESYNC_2_6.py index 7a121cb2a2f0ca..deae1123213a67 100644 --- a/src/python_testing/TC_TIMESYNC_2_6.py +++ b/src/python_testing/TC_TIMESYNC_2_6.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import typing diff --git a/src/python_testing/TC_TIMESYNC_2_7.py b/src/python_testing/TC_TIMESYNC_2_7.py index 0e4e80f87a5548..a405aae1f901a3 100644 --- a/src/python_testing/TC_TIMESYNC_2_7.py +++ b/src/python_testing/TC_TIMESYNC_2_7.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import time import typing diff --git a/src/python_testing/TC_TIMESYNC_2_8.py b/src/python_testing/TC_TIMESYNC_2_8.py index eb78c40cd7318a..418d6e8e41040d 100644 --- a/src/python_testing/TC_TIMESYNC_2_8.py +++ b/src/python_testing/TC_TIMESYNC_2_8.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import time import typing diff --git a/src/python_testing/TC_TIMESYNC_2_9.py b/src/python_testing/TC_TIMESYNC_2_9.py index f52241f9730c24..0fd6872d704684 100644 --- a/src/python_testing/TC_TIMESYNC_2_9.py +++ b/src/python_testing/TC_TIMESYNC_2_9.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import typing from datetime import timedelta diff --git a/src/python_testing/TC_TIMESYNC_3_1.py b/src/python_testing/TC_TIMESYNC_3_1.py index 6d3148872e6ece..ad972345db5828 100644 --- a/src/python_testing/TC_TIMESYNC_3_1.py +++ b/src/python_testing/TC_TIMESYNC_3_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_TestEventTrigger.py b/src/python_testing/TC_TestEventTrigger.py index ee227a8bfbec9d..373fabf704078f 100644 --- a/src/python_testing/TC_TestEventTrigger.py +++ b/src/python_testing/TC_TestEventTrigger.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --bool-arg allow_sdk_dac:true --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging 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/TestBatchInvoke.py b/src/python_testing/TestBatchInvoke.py index 8af874fa7b0b27..230ebc9bbc1705 100644 --- a/src/python_testing/TestBatchInvoke.py +++ b/src/python_testing/TestBatchInvoke.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TestConformanceSupport.py b/src/python_testing/TestConformanceSupport.py index 1405e5c8c791cc..3744b6fe5e70d5 100644 --- a/src/python_testing/TestConformanceSupport.py +++ b/src/python_testing/TestConformanceSupport.py @@ -18,9 +18,10 @@ import xml.etree.ElementTree as ElementTree from typing import Callable -from conformance_support import (ConformanceDecision, ConformanceException, ConformanceParseParameters, deprecated, disallowed, - mandatory, optional, parse_basic_callable_from_xml, parse_callable_from_xml, - parse_device_type_callable_from_xml, provisional, zigbee) +from chip.tlv import uint +from conformance_support import (Choice, Conformance, ConformanceDecision, ConformanceException, ConformanceParseParameters, + deprecated, disallowed, mandatory, optional, parse_basic_callable_from_xml, + parse_callable_from_xml, parse_device_type_callable_from_xml, provisional, zigbee) from matter_testing_support import MatterBaseTest, default_matter_test_main from mobly import asserts @@ -59,7 +60,7 @@ def test_conformance_mandatory(self): et = ElementTree.fromstring(xml) xml_callable = parse_callable_from_xml(et, self.params) for f in self.feature_maps: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.MANDATORY) asserts.assert_equal(str(xml_callable), 'M') def test_conformance_optional(self): @@ -67,7 +68,7 @@ def test_conformance_optional(self): et = ElementTree.fromstring(xml) xml_callable = parse_callable_from_xml(et, self.params) for f in self.feature_maps: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.OPTIONAL) asserts.assert_equal(str(xml_callable), 'O') def test_conformance_disallowed(self): @@ -75,14 +76,14 @@ def test_conformance_disallowed(self): et = ElementTree.fromstring(xml) xml_callable = parse_callable_from_xml(et, self.params) for f in self.feature_maps: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.DISALLOWED) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.DISALLOWED) asserts.assert_equal(str(xml_callable), 'X') xml = '' et = ElementTree.fromstring(xml) xml_callable = parse_callable_from_xml(et, self.params) for f in self.feature_maps: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.DISALLOWED) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.DISALLOWED) asserts.assert_equal(str(xml_callable), 'D') def test_conformance_provisional(self): @@ -90,7 +91,7 @@ def test_conformance_provisional(self): et = ElementTree.fromstring(xml) xml_callable = parse_callable_from_xml(et, self.params) for f in self.feature_maps: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.PROVISIONAL) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.PROVISIONAL) asserts.assert_equal(str(xml_callable), 'P') def test_conformance_zigbee(self): @@ -98,7 +99,7 @@ def test_conformance_zigbee(self): et = ElementTree.fromstring(xml) xml_callable = parse_callable_from_xml(et, self.params) for f in self.feature_maps: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), 'Zigbee') def test_conformance_mandatory_on_condition(self): @@ -109,9 +110,9 @@ def test_conformance_mandatory_on_condition(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if self.has_ab[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), 'AB') xml = ('' @@ -121,9 +122,9 @@ def test_conformance_mandatory_on_condition(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if self.has_cd[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), 'CD') # single attribute mandatory @@ -134,9 +135,9 @@ def test_conformance_mandatory_on_condition(self): xml_callable = parse_callable_from_xml(et, self.params) for i, a in enumerate(self.attribute_lists): if self.has_attr1[i]: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), 'attr1') xml = ('' @@ -146,9 +147,9 @@ def test_conformance_mandatory_on_condition(self): xml_callable = parse_callable_from_xml(et, self.params) for i, a in enumerate(self.attribute_lists): if self.has_attr2[i]: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), 'attr2') # test command in optional and in boolean - this is the same as attribute essentially, so testing every permutation is overkill @@ -162,9 +163,9 @@ def test_conformance_optional_on_condition(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if self.has_ab[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.OPTIONAL) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '[AB]') xml = ('' @@ -174,9 +175,9 @@ def test_conformance_optional_on_condition(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if self.has_cd[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.OPTIONAL) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '[CD]') # single attribute optional @@ -187,9 +188,9 @@ def test_conformance_optional_on_condition(self): xml_callable = parse_callable_from_xml(et, self.params) for i, a in enumerate(self.attribute_lists): if self.has_attr1[i]: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.OPTIONAL) else: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '[attr1]') xml = ('' @@ -199,9 +200,9 @@ def test_conformance_optional_on_condition(self): xml_callable = parse_callable_from_xml(et, self.params) for i, a in enumerate(self.attribute_lists): if self.has_attr2[i]: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.OPTIONAL) else: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '[attr2]') # single command optional @@ -212,9 +213,9 @@ def test_conformance_optional_on_condition(self): xml_callable = parse_callable_from_xml(et, self.params) for i, c in enumerate(self.cmd_lists): if self.has_cmd1[i]: - asserts.assert_equal(xml_callable(0x00, [], c), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(0x00, [], c).decision, ConformanceDecision.OPTIONAL) else: - asserts.assert_equal(xml_callable(0x00, [], c), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(0x00, [], c).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '[cmd1]') xml = ('' @@ -224,9 +225,9 @@ def test_conformance_optional_on_condition(self): xml_callable = parse_callable_from_xml(et, self.params) for i, c in enumerate(self.cmd_lists): if self.has_cmd2[i]: - asserts.assert_equal(xml_callable(0x00, [], c), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(0x00, [], c).decision, ConformanceDecision.OPTIONAL) else: - asserts.assert_equal(xml_callable(0x00, [], c), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(0x00, [], c).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '[cmd2]') def test_conformance_not_term_mandatory(self): @@ -240,9 +241,9 @@ def test_conformance_not_term_mandatory(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if not self.has_ab[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '!AB') xml = ('' @@ -254,9 +255,9 @@ def test_conformance_not_term_mandatory(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if not self.has_cd[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '!CD') # single attribute not mandatory @@ -269,9 +270,9 @@ def test_conformance_not_term_mandatory(self): xml_callable = parse_callable_from_xml(et, self.params) for i, a in enumerate(self.attribute_lists): if not self.has_attr1[i]: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '!attr1') xml = ('' @@ -283,9 +284,9 @@ def test_conformance_not_term_mandatory(self): xml_callable = parse_callable_from_xml(et, self.params) for i, a in enumerate(self.attribute_lists): if not self.has_attr2[i]: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '!attr2') def test_conformance_not_term_optional(self): @@ -299,9 +300,9 @@ def test_conformance_not_term_optional(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if not self.has_ab[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.OPTIONAL) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '[!AB]') xml = ('' @@ -313,9 +314,9 @@ def test_conformance_not_term_optional(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if not self.has_cd[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.OPTIONAL) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '[!CD]') def test_conformance_and_term(self): @@ -330,9 +331,9 @@ def test_conformance_and_term(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if self.has_ab[i] and self.has_cd[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), 'AB & CD') # and term for attributes only @@ -346,9 +347,9 @@ def test_conformance_and_term(self): xml_callable = parse_callable_from_xml(et, self.params) for i, a in enumerate(self.attribute_lists): if self.has_attr1[i] and self.has_attr2[i]: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), 'attr1 & attr2') # and term for feature and attribute @@ -363,9 +364,9 @@ def test_conformance_and_term(self): for i, f in enumerate(self.feature_maps): for j, a in enumerate(self.attribute_lists): if self.has_ab[i] and self.has_attr2[j]: - asserts.assert_equal(xml_callable(f, a, []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(f, a, []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(f, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, a, []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), 'AB & attr2') def test_conformance_or_term(self): @@ -380,9 +381,9 @@ def test_conformance_or_term(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if self.has_ab[i] or self.has_cd[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), 'AB | CD') # or term attribute only @@ -396,9 +397,9 @@ def test_conformance_or_term(self): xml_callable = parse_callable_from_xml(et, self.params) for i, a in enumerate(self.attribute_lists): if self.has_attr1[i] or self.has_attr2[i]: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(0x00, a, []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), 'attr1 | attr2') # or term feature and attribute @@ -413,9 +414,9 @@ def test_conformance_or_term(self): for i, f in enumerate(self.feature_maps): for j, a in enumerate(self.attribute_lists): if self.has_ab[i] or self.has_attr2[j]: - asserts.assert_equal(xml_callable(f, a, []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(f, a, []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(f, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, a, []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), 'AB | attr2') def test_conformance_and_term_with_not(self): @@ -432,9 +433,9 @@ def test_conformance_and_term_with_not(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if not self.has_ab[i] and self.has_cd[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.OPTIONAL) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '[!AB & CD]') def test_conformance_or_term_with_not(self): @@ -451,9 +452,9 @@ def test_conformance_or_term_with_not(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if self.has_ab[i] or not self.has_cd[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), 'AB | !CD') # not around or term with @@ -469,9 +470,9 @@ def test_conformance_or_term_with_not(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if not (self.has_ab[i] or self.has_cd[i]): - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.OPTIONAL) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '[!(AB | CD)]') def test_conformance_and_term_with_three_terms(self): @@ -487,11 +488,11 @@ def test_conformance_and_term_with_three_terms(self): et = ElementTree.fromstring(xml) xml_callable = parse_callable_from_xml(et, self.params) # no features - asserts.assert_equal(xml_callable(0x00, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(0x00, [], []).decision, ConformanceDecision.NOT_APPLICABLE) # one feature - asserts.assert_equal(xml_callable(0x01, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(0x01, [], []).decision, ConformanceDecision.NOT_APPLICABLE) # all features - asserts.assert_equal(xml_callable(0x07, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(0x07, [], []).decision, ConformanceDecision.OPTIONAL) asserts.assert_equal(str(xml_callable), '[AB & CD & EF]') # and term with one of each @@ -508,9 +509,9 @@ def test_conformance_and_term_with_three_terms(self): for j, a in enumerate(self.attribute_lists): for k, c in enumerate(self.cmd_lists): if self.has_ab[i] and self.has_attr1[j] and self.has_cmd1[k]: - asserts.assert_equal(xml_callable(f, a, c), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(f, a, c).decision, ConformanceDecision.OPTIONAL) else: - asserts.assert_equal(xml_callable(f, a, c), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, a, c).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '[AB & attr1 & cmd1]') def test_conformance_or_term_with_three_terms(self): @@ -525,11 +526,11 @@ def test_conformance_or_term_with_three_terms(self): et = ElementTree.fromstring(xml) xml_callable = parse_callable_from_xml(et, self.params) # no features - asserts.assert_equal(xml_callable(0x00, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(0x00, [], []).decision, ConformanceDecision.NOT_APPLICABLE) # one feature - asserts.assert_equal(xml_callable(0x01, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(0x01, [], []).decision, ConformanceDecision.OPTIONAL) # all features - asserts.assert_equal(xml_callable(0x07, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(0x07, [], []).decision, ConformanceDecision.OPTIONAL) asserts.assert_equal(str(xml_callable), '[AB | CD | EF]') # or term with one of each @@ -546,9 +547,9 @@ def test_conformance_or_term_with_three_terms(self): for j, a in enumerate(self.attribute_lists): for k, c in enumerate(self.cmd_lists): if self.has_ab[i] or self.has_attr1[j] or self.has_cmd1[k]: - asserts.assert_equal(xml_callable(f, a, c), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(f, a, c).decision, ConformanceDecision.OPTIONAL) else: - asserts.assert_equal(xml_callable(f, a, c), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, a, c).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), '[AB | attr1 | cmd1]') def test_conformance_otherwise(self): @@ -563,9 +564,9 @@ def test_conformance_otherwise(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if self.has_ab[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.OPTIONAL) asserts.assert_equal(str(xml_callable), 'AB, O') # AB, [CD] @@ -581,11 +582,11 @@ def test_conformance_otherwise(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if self.has_ab[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.MANDATORY) elif self.has_cd[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.OPTIONAL) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.NOT_APPLICABLE) asserts.assert_equal(str(xml_callable), 'AB, [CD]') # AB & !CD, P @@ -604,9 +605,9 @@ def test_conformance_otherwise(self): xml_callable = parse_callable_from_xml(et, self.params) for i, f in enumerate(self.feature_maps): if self.has_ab[i] and not self.has_cd[i]: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.MANDATORY) else: - asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.PROVISIONAL) + asserts.assert_equal(xml_callable(f, [], []).decision, ConformanceDecision.PROVISIONAL) asserts.assert_equal(str(xml_callable), 'AB & !CD, P') def test_conformance_greater(self): @@ -620,7 +621,7 @@ def test_conformance_greater(self): et = ElementTree.fromstring(xml) xml_callable = parse_callable_from_xml(et, self.params) # TODO: switch this to check greater than once the update to the base is done (#33422) - asserts.assert_equal(xml_callable(0x00, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(0x00, [], []).decision, ConformanceDecision.OPTIONAL) asserts.assert_equal(str(xml_callable), 'attr1 > 1') # Ensure that we can only have greater terms with exactly 2 value @@ -705,7 +706,7 @@ def test_device_type_conformance(self): et = ElementTree.fromstring(xml) xml_callable = parse_device_type_callable_from_xml(et) asserts.assert_equal(str(xml_callable), 'Zigbee', msg) - asserts.assert_equal(xml_callable(0, [], []), ConformanceDecision.NOT_APPLICABLE, msg) + asserts.assert_equal(xml_callable(0, [], []).decision, ConformanceDecision.NOT_APPLICABLE, msg) xml = ('' '' @@ -714,7 +715,7 @@ def test_device_type_conformance(self): xml_callable = parse_device_type_callable_from_xml(et) # expect no exception here asserts.assert_equal(str(xml_callable), '[Zigbee]', msg) - asserts.assert_equal(xml_callable(0, [], []), ConformanceDecision.NOT_APPLICABLE, msg) + asserts.assert_equal(xml_callable(0, [], []).decision, ConformanceDecision.NOT_APPLICABLE, msg) # otherwise conforms are allowed xml = ('' @@ -725,7 +726,7 @@ def test_device_type_conformance(self): xml_callable = parse_device_type_callable_from_xml(et) # expect no exception here asserts.assert_equal(str(xml_callable), 'Zigbee, P', msg) - asserts.assert_equal(xml_callable(0, [], []), ConformanceDecision.PROVISIONAL, msg) + asserts.assert_equal(xml_callable(0, [], []).decision, ConformanceDecision.PROVISIONAL, msg) # Device type conditions or features don't correspond to anything in the spec, so the XML takes a best # guess as to what they are. We should be able to parse features, conditions, attributes as the same @@ -739,7 +740,7 @@ def test_device_type_conformance(self): xml_callable = parse_device_type_callable_from_xml(et) asserts.assert_equal(str(xml_callable), 'CD', msg) # Device features are always optional (at least for now), even though we didn't pass this feature in - asserts.assert_equal(xml_callable(0, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(0, [], []).decision, ConformanceDecision.OPTIONAL) xml = ('' '' @@ -748,7 +749,208 @@ def test_device_type_conformance(self): et = ElementTree.fromstring(xml) xml_callable = parse_device_type_callable_from_xml(et) asserts.assert_equal(str(xml_callable), 'CD, testy', msg) - asserts.assert_equal(xml_callable(0, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(xml_callable(0, [], []).decision, ConformanceDecision.OPTIONAL) + + def check_good_choice(self, xml: str, conformance_str: str) -> Conformance: + et = ElementTree.fromstring(xml) + xml_callable = parse_callable_from_xml(et, self.params) + asserts.assert_equal(str(xml_callable), conformance_str, 'Bad choice conformance string') + return xml_callable + + def check_decision(self, more_expected: bool, conformance: Conformance, feature_map: uint, attr_list: list[uint], cmd_list: list[uint]): + decision = conformance(feature_map, attr_list, cmd_list) + asserts.assert_true(decision.choice, 'Expected choice conformance on decision, but did not get one') + asserts.assert_equal(decision.choice.marker, 'a', 'Unexpected conformance string returned') + asserts.assert_equal(decision.choice.more, more_expected, "Unexpected more on choice") + + def test_choice_conformance(self): + # Choice conformances can appear on: + # - base optional O.a + # - base optional feature [AB].a + # - base optional attribute [attr1].a + # - base optional command [cmd1].a + # - optional wrapper of complex feature [AB | CD].a, [!attr1].a + # - otherwise conformance attr1, [AB], O.a / attr1, [AB].a, O + # - multiple in otherwise [AB].a, [CD].b + # + # Choice conformances are disallowed on: + # - mandatory M.a + # - mandatory feature AB.a + # - mandatory attribute attr1.a + # - mandatory command cmd1.a + # - AND expressions (attr1 & O.a) + # - OR expressions (attr1 | O.a) + # - NOT expressions (!O.a) + # - internal expressions [AB.a], [attr1.a], [cmd1.a] + # - provisional P.a + # - disallowed X.a + # - deprecated D.a + + choices = [('a+', 'choice="a" more="true"', True), ('a', 'choice="a"', False)] + for suffix, xml_attrs, more in choices: + + AB = self.feature_names_to_bits['AB'] + attr1 = [self.attribute_names_to_values['attr1']] + cmd1 = [self.command_names_to_values['cmd1']] + + msg_not_applicable = "Expected NOT_APPLICABLE conformance" + xml = f'' + conformance = self.check_good_choice(xml, f'O.{suffix}') + self.check_decision(more, conformance, 0, [], []) + + xml = (f'' + '' + '') + conformance = self.check_good_choice(xml, f'[AB].{suffix}') + asserts.assert_equal(conformance(0, [], []).decision, ConformanceDecision.NOT_APPLICABLE, msg_not_applicable) + self.check_decision(more, conformance, AB, [], []) + + xml = (f'' + '' + '') + conformance = self.check_good_choice(xml, f'[attr1].{suffix}') + asserts.assert_equal(conformance(0, [], []).decision, ConformanceDecision.NOT_APPLICABLE, msg_not_applicable) + self.check_decision(more, conformance, 0, attr1, []) + + xml = (f'' + '' + '') + conformance = self.check_good_choice(xml, f'[cmd1].{suffix}') + asserts.assert_equal(conformance(0, [], []).decision, ConformanceDecision.NOT_APPLICABLE, msg_not_applicable) + self.check_decision(more, conformance, 0, [], cmd1) + + xml = (f'' + '' + '' + '' + '' + '') + conformance = self.check_good_choice(xml, f'[AB | CD].{suffix}') + asserts.assert_equal(conformance(0, [], []).decision, ConformanceDecision.NOT_APPLICABLE, msg_not_applicable) + self.check_decision(more, conformance, AB, [], []) + + xml = (f'' + '' + '' + '' + '') + conformance = self.check_good_choice(xml, f'[!attr1].{suffix}') + asserts.assert_equal(conformance(0, attr1, []).decision, ConformanceDecision.NOT_APPLICABLE, msg_not_applicable) + self.check_decision(more, conformance, 0, [], []) + + xml = ('' + '' + f'' + '' + '' + f'' + '') + conformance = self.check_good_choice(xml, f'attr1, [AB], O.{suffix}') + # with no features or attributes, this should end up as O.a, so there should be a choice + self.check_decision(more, conformance, 0, [], []) + # when we have this attribute, we should not have a choice + asserts.assert_equal(conformance(0, attr1, []).decision, ConformanceDecision.MANDATORY, 'Unexpected conformance') + asserts.assert_equal(conformance(0, attr1, []).choice, None, 'Unexpected choice in conformance') + # when we have only this feature, we should not have a choice + asserts.assert_equal(conformance(AB, [], []).decision, ConformanceDecision.OPTIONAL, 'Unexpected conformance') + asserts.assert_equal(conformance(AB, [], []).choice, None, 'Unexpected choice in conformance') + + # - multiple in otherwise [AB].a, [CD].b + xml = ('' + '' + f'' + '' + '' + f'' + '' + '' + '') + conformance = self.check_good_choice(xml, f'attr1, [AB].{suffix}, [CD].b') + asserts.assert_equal(conformance(0, [], []).decision, ConformanceDecision.NOT_APPLICABLE, msg_not_applicable) + # when we have this attribute, we should not have a choice + asserts.assert_equal(conformance(0, attr1, []).decision, ConformanceDecision.MANDATORY, 'Unexpected conformance') + asserts.assert_equal(conformance(0, attr1, []).choice, None, 'Unexpected choice in conformance') + # When it's just AB, we should have a choice + self.check_decision(more, conformance, AB, [], []) + # When we have both the attribute and AB, we should not have a choice + asserts.assert_equal(conformance(0, attr1, []).decision, ConformanceDecision.MANDATORY, 'Unexpected conformance') + asserts.assert_equal(conformance(0, attr1, []).choice, None, 'Unexpected choice in conformance') + # When we have AB and CD, we should be using the AB choice + CD = self.feature_names_to_bits['CD'] + ABCD = AB | CD + self.check_decision(more, conformance, ABCD, [], []) + # When we just have CD, we still have a choice, but the string should be b + asserts.assert_equal(conformance(CD, [], []).decision, ConformanceDecision.OPTIONAL, 'Unexpected conformance') + asserts.assert_equal(conformance(CD, [], []).choice, Choice('b', False), 'Unexpected choice in conformance') + + # Ones that should throw exceptions + + def check_bad_choice(xml: str): + msg = f'Choice conformance string should cause exception, but did not: {xml}' + et = ElementTree.fromstring(xml) + try: + parse_callable_from_xml(et, self.params) + asserts.fail(msg) + except ConformanceException: + pass + xml = f'' + check_bad_choice(xml) + + xml = f'' + check_bad_choice(xml) + + xml = f'' + check_bad_choice(xml) + + xml = f'' + check_bad_choice(xml) + + xml = ('' + '' + '' + f'' + '' + '') + check_bad_choice(xml) + + xml = ('' + '' + '' + f'' + '' + '') + check_bad_choice(xml) + + xml = ('' + '' + f'' + '' + '') + check_bad_choice(xml) + + xml = ('' + f'' + '') + check_bad_choice(xml) + + xml = ('' + f'' + '') + check_bad_choice(xml) + + xml = ('' + f'' + '') + check_bad_choice(xml) + + xml = (f'') + check_bad_choice(xml) + + xml = (f'') + check_bad_choice(xml) + + xml = (f'') + check_bad_choice(xml) if __name__ == "__main__": diff --git a/src/python_testing/TestGroupTableReports.py b/src/python_testing/TestGroupTableReports.py index d827752f1ee176..cc9b9a0718a25e 100644 --- a/src/python_testing/TestGroupTableReports.py +++ b/src/python_testing/TestGroupTableReports.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # 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 +# === END CI TEST ARGUMENTS === import logging import queue 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/TestSpecParsingSupport.py b/src/python_testing/TestSpecParsingSupport.py index c35a5eb0f6bb22..fadd6a517a4531 100644 --- a/src/python_testing/TestSpecParsingSupport.py +++ b/src/python_testing/TestSpecParsingSupport.py @@ -377,8 +377,7 @@ def test_known_aliased_clusters(self): (0x040D, 'Carbon Dioxide Concentration Measurement', 'CDOCONC'), (0x0413, 'Nitrogen Dioxide Concentration Measurement', 'NDOCONC'), (0x0415, 'Ozone Concentration Measurement', 'OZCONC'), - # Change to "PM2.5 Concentration Measurement" once https://github.com/csa-data-model/projects/issues/453 is fixed - (0x042A, 'PM2', 'PMICONC'), + (0x042A, 'PM2.5 Concentration Measurement', 'PMICONC'), (0x042B, 'Formaldehyde Concentration Measurement', 'FLDCONC'), (0x042C, 'PM1 Concentration Measurement', 'PMHCONC'), (0x042D, 'PM10 Concentration Measurement', 'PMKCONC'), diff --git a/src/python_testing/conformance_support.py b/src/python_testing/conformance_support.py index c9bdb5830c884b..6e439f1deb2b4d 100644 --- a/src/python_testing/conformance_support.py +++ b/src/python_testing/conformance_support.py @@ -18,7 +18,7 @@ import xml.etree.ElementTree as ElementTree from dataclasses import dataclass from enum import Enum, auto -from typing import Callable +from typing import Callable, Optional from chip.tlv import uint @@ -50,6 +50,35 @@ def __str__(self): return f"ConformanceException({self.msg})" +class ChoiceConformanceException(ConformanceException): + def __str__(self): + return f'ChoiceExceptions({self.msg})' + + +class BasicConformanceException(ConformanceException): + pass + + +@dataclass(frozen=True) +class Choice: + marker: str + more: bool + + def __str__(self): + more_str = '+' if self.more else '' + return '.' + self.marker + more_str + + +def parse_choice(element: ElementTree.Element) -> Optional[Choice]: + choice = element.get('choice', '') + if not choice: + return None + if element.tag != OPTIONAL_CONFORM: + raise ChoiceConformanceException('Choice conformance on non-optional attribute') + more = element.get('more', 'false') == 'true' + return Choice(choice, more) + + class ConformanceDecision(Enum): MANDATORY = auto() OPTIONAL = auto() @@ -58,6 +87,12 @@ class ConformanceDecision(Enum): PROVISIONAL = auto() +@dataclass +class ConformanceDecisionWithChoice: + decision: ConformanceDecision + choice: Optional[Choice] = None + + @dataclass class ConformanceParseParameters: feature_map: dict[str, uint] @@ -65,68 +100,87 @@ class ConformanceParseParameters: command_map: dict[str, uint] -def conformance_allowed(conformance_decision: ConformanceDecision, allow_provisional: bool): - if conformance_decision == ConformanceDecision.NOT_APPLICABLE or conformance_decision == ConformanceDecision.DISALLOWED: +def conformance_allowed(conformance_decision: ConformanceDecisionWithChoice, allow_provisional: bool): + if conformance_decision.decision in [ConformanceDecision.NOT_APPLICABLE, ConformanceDecision.DISALLOWED]: return False - if conformance_decision == ConformanceDecision.PROVISIONAL: + if conformance_decision.decision == ConformanceDecision.PROVISIONAL: return allow_provisional return True def is_disallowed(conformance: Callable): # Deprecated and disallowed conformances will come back as disallowed regardless of the implemented features / attributes / etc. - return conformance(0, [], []) == ConformanceDecision.DISALLOWED + return conformance(0, [], []).decision == ConformanceDecision.DISALLOWED + + +@dataclass +class Conformance(Callable): + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: + ''' Evaluates the conformance of a specific cluster or device type element. + + feature_map: The feature_map for the given cluster for which this conformance applies. Used to evaluate feature conformances + attribute_list: The attribute list for the given cluster for which this conformance applied. Used to evaluate attribute conformances + all_command_list: combined list of accepted and generated command IDs for the cluster. Used to evaluate command conformances + Returns: ConformanceDevisionWithChoice + Raises: ConformanceException if the conformance is invalid + ''' + raise ConformanceException('Base conformance called') + choice: Optional[Choice] = None -class zigbee: - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - return ConformanceDecision.NOT_APPLICABLE + +class zigbee(Conformance): + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: + return ConformanceDecisionWithChoice(ConformanceDecision.NOT_APPLICABLE) def __str__(self): return "Zigbee" -class mandatory: - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - return ConformanceDecision.MANDATORY +class mandatory(Conformance): + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: + return ConformanceDecisionWithChoice(ConformanceDecision.MANDATORY) def __str__(self): return 'M' -class optional: - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - return ConformanceDecision.OPTIONAL +class optional(Conformance): + def __init__(self, choice: Optional[Choice] = None): + self.choice = choice + + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: + return ConformanceDecisionWithChoice(ConformanceDecision.OPTIONAL, self.choice) def __str__(self): - return 'O' + return 'O' + (str(self.choice) if self.choice else '') -class deprecated: - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - return ConformanceDecision.DISALLOWED +class deprecated(Conformance): + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: + return ConformanceDecisionWithChoice(ConformanceDecision.DISALLOWED) def __str__(self): return 'D' -class disallowed: - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - return ConformanceDecision.DISALLOWED +class disallowed(Conformance): + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: + return ConformanceDecisionWithChoice(ConformanceDecision.DISALLOWED) def __str__(self): return 'X' -class provisional: - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - return ConformanceDecision.PROVISIONAL +class provisional(Conformance): + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: + return ConformanceDecisionWithChoice(ConformanceDecision.PROVISIONAL) def __str__(self): return 'P' -class literal: +class literal(Conformance): def __init__(self, value: str): self.value = int(value) @@ -148,56 +202,56 @@ def __str__(self): } -class feature: +class feature(Conformance): def __init__(self, requiredFeature: uint, code: str): self.requiredFeature = requiredFeature self.code = code - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: if self.requiredFeature & feature_map != 0: - return ConformanceDecision.MANDATORY - return ConformanceDecision.NOT_APPLICABLE + return ConformanceDecisionWithChoice(ConformanceDecision.MANDATORY) + return ConformanceDecisionWithChoice(ConformanceDecision.NOT_APPLICABLE) def __str__(self): return self.code -class device_feature: +class device_feature(Conformance): ''' This is different than element feature because device types use "features" that aren't reported anywhere''' def __init__(self, feature: str): self.feature = feature - def __call__(self, feature_map: uint = 0, attribute_list: list[uint] = [], all_command_list: list[uint] = []) -> ConformanceDecision: - return ConformanceDecision.OPTIONAL + def __call__(self, feature_map: uint = 0, attribute_list: list[uint] = [], all_command_list: list[uint] = []) -> ConformanceDecisionWithChoice: + return ConformanceDecisionWithChoice(ConformanceDecision.OPTIONAL) def __str__(self): return self.feature -class attribute: +class attribute(Conformance): def __init__(self, requiredAttribute: uint, name: str): self.requiredAttribute = requiredAttribute self.name = name - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: if self.requiredAttribute in attribute_list: - return ConformanceDecision.MANDATORY - return ConformanceDecision.NOT_APPLICABLE + return ConformanceDecisionWithChoice(ConformanceDecision.MANDATORY) + return ConformanceDecisionWithChoice(ConformanceDecision.NOT_APPLICABLE) def __str__(self): return self.name -class command: +class command(Conformance): def __init__(self, requiredCommand: uint, name: str): self.requiredCommand = requiredCommand self.name = name - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: if self.requiredCommand in all_command_list: - return ConformanceDecision.MANDATORY - return ConformanceDecision.NOT_APPLICABLE + return ConformanceDecisionWithChoice(ConformanceDecision.MANDATORY) + return ConformanceDecisionWithChoice(ConformanceDecision.NOT_APPLICABLE) def __str__(self): return self.name @@ -209,52 +263,56 @@ def strip_outer_parentheses(inner: str) -> str: return inner -class optional_wrapper: - def __init__(self, op: Callable): +class optional_wrapper(Conformance): + def __init__(self, op: Callable, choice: Optional[Choice] = None): self.op = op + self.choice = choice - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - decision = self.op(feature_map, attribute_list, all_command_list) - if decision == ConformanceDecision.MANDATORY or decision == ConformanceDecision.OPTIONAL: - return ConformanceDecision.OPTIONAL - elif decision == ConformanceDecision.NOT_APPLICABLE: - return ConformanceDecision.NOT_APPLICABLE + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: + decision_with_choice = self.op(feature_map, attribute_list, all_command_list) + + if decision_with_choice.decision in [ConformanceDecision.MANDATORY, ConformanceDecision.OPTIONAL]: + return ConformanceDecisionWithChoice(ConformanceDecision.OPTIONAL, self.choice) + elif decision_with_choice.decision == ConformanceDecision.NOT_APPLICABLE: + return decision_with_choice else: - raise ConformanceException(f'Optional wrapping invalid op {decision}') + raise ConformanceException(f'Optional wrapping invalid op {decision_with_choice}') def __str__(self): - return f'[{strip_outer_parentheses(str(self.op))}]' + return f'[{strip_outer_parentheses(str(self.op))}]' + (str(self.choice) if self.choice else '') -class mandatory_wrapper: +class mandatory_wrapper(Conformance): def __init__(self, op: Callable): self.op = op - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: return self.op(feature_map, attribute_list, all_command_list) def __str__(self): return strip_outer_parentheses(str(self.op)) -class not_operation: +class not_operation(Conformance): def __init__(self, op: Callable): + if op.choice: + raise ChoiceConformanceException('NOT operation called on choice conformance') self.op = op - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: # not operations can't be used with anything that returns DISALLOWED # not operations also can't be used with things that are optional # ie, ![AB] doesn't make sense, nor does !O - decision = self.op(feature_map, attribute_list, all_command_list) - if decision == ConformanceDecision.DISALLOWED or decision == ConformanceDecision.PROVISIONAL: + decision_with_choice = self.op(feature_map, attribute_list, all_command_list) + if decision_with_choice.decision in [ConformanceDecision.DISALLOWED, ConformanceDecision.PROVISIONAL]: raise ConformanceException('NOT operation on optional or disallowed item') # Features in device types degrade to optional so a not operation here is still optional because we don't have any way to verify the features since they're not exposed anywhere - elif decision == ConformanceDecision.OPTIONAL: - return ConformanceDecision.OPTIONAL - elif decision == ConformanceDecision.NOT_APPLICABLE: - return ConformanceDecision.MANDATORY - elif decision == ConformanceDecision.MANDATORY: - return ConformanceDecision.NOT_APPLICABLE + elif decision_with_choice.decision == ConformanceDecision.OPTIONAL: + return decision_with_choice + elif decision_with_choice.decision == ConformanceDecision.NOT_APPLICABLE: + return ConformanceDecisionWithChoice(ConformanceDecision.MANDATORY) + elif decision_with_choice.decision == ConformanceDecision.MANDATORY: + return ConformanceDecisionWithChoice(ConformanceDecision.NOT_APPLICABLE) else: raise ConformanceException('NOT called on item with non-conformance value') @@ -262,54 +320,58 @@ def __str__(self): return f'!{str(self.op)}' -class and_operation: +class and_operation(Conformance): def __init__(self, op_list: list[Callable]): + for op in op_list: + if op.choice: + raise ChoiceConformanceException('AND operation with internal choice conformance') self.op_list = op_list - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: for op in self.op_list: - decision = op(feature_map, attribute_list, all_command_list) + decision_with_choice = op(feature_map, attribute_list, all_command_list) # and operations can't happen on optional or disallowed - if decision == ConformanceDecision.OPTIONAL or decision == ConformanceDecision.DISALLOWED or decision == ConformanceDecision.PROVISIONAL: + if decision_with_choice.decision in [ConformanceDecision.OPTIONAL, ConformanceDecision.DISALLOWED, ConformanceDecision.PROVISIONAL]: raise ConformanceException('AND operation on optional or disallowed item') - elif decision == ConformanceDecision.NOT_APPLICABLE: - return ConformanceDecision.NOT_APPLICABLE - elif decision == ConformanceDecision.MANDATORY: + elif decision_with_choice.decision == ConformanceDecision.NOT_APPLICABLE: + return decision_with_choice + elif decision_with_choice.decision == ConformanceDecision.MANDATORY: continue else: raise ConformanceException('Oplist item returned non-conformance value') - return ConformanceDecision.MANDATORY + return ConformanceDecisionWithChoice(ConformanceDecision.MANDATORY) def __str__(self): op_strs = [str(op) for op in self.op_list] return f'({" & ".join(op_strs)})' -class or_operation: +class or_operation(Conformance): def __init__(self, op_list: list[Callable]): + for op in op_list: + if op.choice: + raise ChoiceConformanceException('AND operation with internal choice conformance') self.op_list = op_list - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: for op in self.op_list: - decision = op(feature_map, attribute_list, all_command_list) - if decision == ConformanceDecision.DISALLOWED or decision == ConformanceDecision.PROVISIONAL: + decision_with_choice = op(feature_map, attribute_list, all_command_list) + if decision_with_choice.decision in [ConformanceDecision.DISALLOWED, ConformanceDecision.PROVISIONAL]: raise ConformanceException('OR operation on optional or disallowed item') - elif decision == ConformanceDecision.NOT_APPLICABLE: + elif decision_with_choice.decision == ConformanceDecision.NOT_APPLICABLE: continue - elif decision == ConformanceDecision.MANDATORY: - return ConformanceDecision.MANDATORY - elif decision == ConformanceDecision.OPTIONAL: - return ConformanceDecision.OPTIONAL + elif decision_with_choice.decision in [ConformanceDecision.MANDATORY, ConformanceDecision.OPTIONAL]: + return decision_with_choice else: raise ConformanceException('Oplist item returned non-conformance value') - return ConformanceDecision.NOT_APPLICABLE + return ConformanceDecisionWithChoice(ConformanceDecision.NOT_APPLICABLE) def __str__(self): op_strs = [str(op) for op in self.op_list] return f'({" | ".join(op_strs)})' -class greater_operation: +class greater_operation(Conformance): def _type_ok(self, op: Callable): return type(op) == attribute or type(op) == literal @@ -319,21 +381,21 @@ def __init__(self, op1: Callable, op2: Callable): self.op1 = op1 self.op2 = op2 - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: # For now, this is fully optional, need to implement this properly later, but it requires access to the actual attribute values # We need to reach into the attribute, but can't use it directly because the attribute callable is an EXISTENCE check and # the arithmetic functions require a value. - return ConformanceDecision.OPTIONAL + return ConformanceDecisionWithChoice(ConformanceDecision.OPTIONAL) def __str__(self): return f'{str(self.op1)} > {str(self.op2)}' -class otherwise: +class otherwise(Conformance): def __init__(self, op_list: list[Callable]): self.op_list = op_list - def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecisionWithChoice: # Otherwise operations apply from left to right. If any of them # has a definite decision (optional, mandatory or disallowed), that is the one that applies # Provisional items are meant to be marked as the first item in the list @@ -341,11 +403,11 @@ def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_li # For O,D, optional applies (leftmost), but we should consider some way to warn here as well, # possibly in another function for op in self.op_list: - decision = op(feature_map, attribute_list, all_command_list) - if decision == ConformanceDecision.NOT_APPLICABLE: + decision_with_choice = op(feature_map, attribute_list, all_command_list) + if decision_with_choice.decision == ConformanceDecision.NOT_APPLICABLE: continue - return decision - return ConformanceDecision.NOT_APPLICABLE + return decision_with_choice + return ConformanceDecisionWithChoice(ConformanceDecision.NOT_APPLICABLE) def __str__(self): op_strs = [strip_outer_parentheses(str(op)) for op in self.op_list] @@ -354,9 +416,12 @@ def __str__(self): def parse_basic_callable_from_xml(element: ElementTree.Element) -> Callable: if list(element): - raise ConformanceException("parse_basic_callable_from_xml called for XML element with children") + raise BasicConformanceException("parse_basic_callable_from_xml called for XML element with children") # This will throw a key error if this is not a basic element key. try: + choice = parse_choice(element) + if choice and element.tag == OPTIONAL_CONFORM: + return optional(choice) return BASIC_CONFORMANCE[element.tag] except KeyError: if element.tag == CONDITION_TAG and element.get('name').lower() == ZIGBEE_CONDITION: @@ -364,17 +429,18 @@ def parse_basic_callable_from_xml(element: ElementTree.Element) -> Callable: elif element.tag == LITERAL_TAG: return literal(element.get('value')) else: - raise ConformanceException( + raise BasicConformanceException( f'parse_basic_callable_from_xml called for unknown element {str(element.tag)} {str(element.attrib)}') def parse_wrapper_callable_from_xml(element: ElementTree.Element, ops: list[Callable]) -> Callable: # optional can be a wrapper as well as a standalone # This can be any of the boolean operations, optional or otherwise + choice = parse_choice(element) if element.tag == OPTIONAL_CONFORM: if len(ops) > 1: raise ConformanceException(f'OPTIONAL term found with more than one subelement {list(element)}') - return optional_wrapper(ops[0]) + return optional_wrapper(ops[0], choice) elif element.tag == MANDATORY_CONFORM: if len(ops) > 1: raise ConformanceException(f'MANDATORY term found with more than one subelement {list(element)}') @@ -407,7 +473,7 @@ def parse_device_type_callable_from_xml(element: ElementTree.Element) -> Callabl # actually exposed anywhere ON the device other than through the presence of the cluster. So for now, treat any attribute conditions that are cluster conditions # as just optional, because it's optional to implement any device type feature. # Device types also have some marked as "condition" that are similarly optional - except ConformanceException: + except BasicConformanceException: if element.tag == ATTRIBUTE_TAG or element.tag == CONDITION_TAG or element.tag == FEATURE_TAG: return device_feature(element.attrib['name']) raise @@ -420,7 +486,7 @@ def parse_callable_from_xml(element: ElementTree.Element, params: ConformancePar if not list(element): try: return parse_basic_callable_from_xml(element) - except ConformanceException: + except BasicConformanceException: # If we get an exception here, it wasn't a basic type, so move on and check if its # something else. pass diff --git a/src/python_testing/hello_test.py b/src/python_testing/hello_test.py index 01657bf1bded6a..041f28ebeefb0d 100644 --- a/src/python_testing/hello_test.py +++ b/src/python_testing/hello_test.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${TYPE_OF_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 +# === END CI TEST ARGUMENTS === import logging 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/setup_payload/tests/TestAdditionalDataPayload.cpp b/src/setup_payload/tests/TestAdditionalDataPayload.cpp index d59eac34a0b20b..c0671994ff96b4 100644 --- a/src/setup_payload/tests/TestAdditionalDataPayload.cpp +++ b/src/setup_payload/tests/TestAdditionalDataPayload.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include 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..6fb830d6e75e35 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") @@ -29,6 +30,7 @@ if (matter_enable_tracing_support && ] public_deps = [ + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/platform", "${chip_root}/src/tracing", "${chip_root}/src/tracing:macros", diff --git a/src/tracing/tests/TestMetricEvents.cpp b/src/tracing/tests/TestMetricEvents.cpp index a0190265d57e0b..20c6f7788ad69e 100644 --- a/src/tracing/tests/TestMetricEvents.cpp +++ b/src/tracing/tests/TestMetricEvents.cpp @@ -13,7 +13,10 @@ * 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..b3e4e87562397a 100644 --- a/src/tracing/tests/TestTracing.cpp +++ b/src/tracing/tests/TestTracing.cpp @@ -13,7 +13,10 @@ * 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/SessionManager.cpp b/src/transport/SessionManager.cpp index ffb3633b289e21..e22f0722d7cb55 100644 --- a/src/transport/SessionManager.cpp +++ b/src/transport/SessionManager.cpp @@ -339,6 +339,8 @@ CHIP_ERROR SessionManager::PrepareMessage(const SessionHandle & sessionHandle, P return CHIP_ERROR_INTERNAL; } + ReturnErrorOnFailure(packetHeader.EncodeBeforeData(message)); + #if CHIP_PROGRESS_LOGGING CompressedFabricId compressedFabricId = kUndefinedCompressedFabricId; @@ -372,19 +374,26 @@ CHIP_ERROR SessionManager::PrepareMessage(const SessionHandle & sessionHandle, P char typeStr[4 + 1 + 2 + 1]; snprintf(typeStr, sizeof(typeStr), "%04X:%02X", payloadHeader.GetProtocolID().GetProtocolId(), payloadHeader.GetMessageType()); + // More work around pigweed not allowing more than 14 format args in a log + // message when using tokenized logs. + // ChipLogFormatExchangeId logs the numeric exchange ID (at most 5 chars, + // since it's a uint16_t) and one char for initiator/responder. Plus we + // need a null-terminator. + char exchangeStr[5 + 1 + 1]; + snprintf(exchangeStr, sizeof(exchangeStr), ChipLogFormatExchangeId, ChipLogValueExchangeIdFromSentHeader(payloadHeader)); + // // Legend that can be used to decode this log line can be found in messaging/README.md // ChipLogProgress(ExchangeManager, - "<<< [E:" ChipLogFormatExchangeId " S:%u M:" ChipLogFormatMessageCounter - "%s] (%s) Msg TX to %u:" ChipLogFormatX64 " [%04X] [%s] --- Type %s (%s:%s)", - ChipLogValueExchangeIdFromSentHeader(payloadHeader), sessionHandle->SessionIdForLogging(), - packetHeader.GetMessageCounter(), ackBuf, Transport::GetSessionTypeString(sessionHandle), fabricIndex, - ChipLogValueX64(destination), static_cast(compressedFabricId), addressStr, typeStr, protocolName, - msgTypeName); + "<<< [E:%s S:%u M:" ChipLogFormatMessageCounter "%s] (%s) Msg TX to %u:" ChipLogFormatX64 + " [%04X] [%s] --- Type %s (%s:%s) (B:%u)", + exchangeStr, sessionHandle->SessionIdForLogging(), packetHeader.GetMessageCounter(), ackBuf, + Transport::GetSessionTypeString(sessionHandle), fabricIndex, ChipLogValueX64(destination), + static_cast(compressedFabricId), addressStr, typeStr, protocolName, msgTypeName, + static_cast(message->TotalLength())); #endif - ReturnErrorOnFailure(packetHeader.EncodeBeforeData(message)); preparedMessage = EncryptedPacketBufferHandle::MarkEncrypted(std::move(message)); return CHIP_NO_ERROR; diff --git a/src/transport/raw/tests/BUILD.gn b/src/transport/raw/tests/BUILD.gn index 1ac84f3d097700..195e164ec32c73 100644 --- a/src/transport/raw/tests/BUILD.gn +++ b/src/transport/raw/tests/BUILD.gn @@ -54,6 +54,7 @@ chip_test_suite("tests") { ":helpers", "${chip_root}/src/inet/tests:helpers", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/transport", diff --git a/src/transport/raw/tests/TestMessageHeader.cpp b/src/transport/raw/tests/TestMessageHeader.cpp index 4c807afc5c3608..27bbf74790bf97 100644 --- a/src/transport/raw/tests/TestMessageHeader.cpp +++ b/src/transport/raw/tests/TestMessageHeader.cpp @@ -23,9 +23,10 @@ * */ -#include +#include #include +#include #include #include #include diff --git a/src/transport/raw/tests/TestPeerAddress.cpp b/src/transport/raw/tests/TestPeerAddress.cpp index d96bc1990e0755..a4561ad4ebdc4c 100644 --- a/src/transport/raw/tests/TestPeerAddress.cpp +++ b/src/transport/raw/tests/TestPeerAddress.cpp @@ -21,11 +21,12 @@ #include #include -#include +#include #include #include #include +#include #include namespace { diff --git a/src/transport/raw/tests/TestTCP.cpp b/src/transport/raw/tests/TestTCP.cpp index 4f78da5dcdce86..80531491f288a0 100644 --- a/src/transport/raw/tests/TestTCP.cpp +++ b/src/transport/raw/tests/TestTCP.cpp @@ -28,11 +28,12 @@ #include #include -#include +#include #include #include #include +#include #include #include #include diff --git a/src/transport/raw/tests/TestUDP.cpp b/src/transport/raw/tests/TestUDP.cpp index 39167b89a58bb7..d96a781237d18b 100644 --- a/src/transport/raw/tests/TestUDP.cpp +++ b/src/transport/raw/tests/TestUDP.cpp @@ -25,9 +25,10 @@ #include -#include +#include #include +#include #include #include #include diff --git a/src/transport/retransmit/tests/BUILD.gn b/src/transport/retransmit/tests/BUILD.gn index cd762b2c755571..23482412716463 100644 --- a/src/transport/retransmit/tests/BUILD.gn +++ b/src/transport/retransmit/tests/BUILD.gn @@ -25,5 +25,8 @@ chip_test_suite("tests") { test_sources = [ "TestCache.cpp" ] - public_deps = [ "${chip_root}/src/transport/retransmit" ] + public_deps = [ + "${chip_root}/src/lib/core:string-builder-adapters", + "${chip_root}/src/transport/retransmit", + ] } diff --git a/src/transport/retransmit/tests/TestCache.cpp b/src/transport/retransmit/tests/TestCache.cpp index 6142f4910dbf44..09e8cced0f1101 100644 --- a/src/transport/retransmit/tests/TestCache.cpp +++ b/src/transport/retransmit/tests/TestCache.cpp @@ -14,10 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include #include -#include + +#include + +#include +#include // Helpers for simple payload management namespace { diff --git a/src/transport/tests/BUILD.gn b/src/transport/tests/BUILD.gn index 7c38cea5e7e8eb..f0be95ff5ac8dd 100644 --- a/src/transport/tests/BUILD.gn +++ b/src/transport/tests/BUILD.gn @@ -57,6 +57,7 @@ chip_test_suite("tests") { "${chip_root}/src/credentials/tests:cert_test_vectors", "${chip_root}/src/inet/tests:helpers", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/lib/support:testing", "${chip_root}/src/protocols", diff --git a/src/transport/tests/TestCryptoContext.cpp b/src/transport/tests/TestCryptoContext.cpp index 45c3f3e5eb441e..76194a795ff531 100644 --- a/src/transport/tests/TestCryptoContext.cpp +++ b/src/transport/tests/TestCryptoContext.cpp @@ -18,10 +18,11 @@ #include -#include +#include #include #include +#include #include #include diff --git a/src/transport/tests/TestGroupMessageCounter.cpp b/src/transport/tests/TestGroupMessageCounter.cpp index 72fe57754e8976..266decb34ce614 100644 --- a/src/transport/tests/TestGroupMessageCounter.cpp +++ b/src/transport/tests/TestGroupMessageCounter.cpp @@ -22,8 +22,10 @@ */ #include -#include +#include + +#include #include #include #include diff --git a/src/transport/tests/TestPeerConnections.cpp b/src/transport/tests/TestPeerConnections.cpp index 9beb263f1d15c8..5da94eb66dd708 100644 --- a/src/transport/tests/TestPeerConnections.cpp +++ b/src/transport/tests/TestPeerConnections.cpp @@ -23,9 +23,10 @@ * */ -#include +#include #include +#include #include #include diff --git a/src/transport/tests/TestPeerMessageCounter.cpp b/src/transport/tests/TestPeerMessageCounter.cpp index 75f296b1bcba21..6b0c151d9209cc 100644 --- a/src/transport/tests/TestPeerMessageCounter.cpp +++ b/src/transport/tests/TestPeerMessageCounter.cpp @@ -24,8 +24,9 @@ #include #include -#include +#include +#include #include #include diff --git a/src/transport/tests/TestSecureSession.cpp b/src/transport/tests/TestSecureSession.cpp index 672ba04e8fd38c..695f6642b79d3c 100644 --- a/src/transport/tests/TestSecureSession.cpp +++ b/src/transport/tests/TestSecureSession.cpp @@ -24,10 +24,11 @@ #include #include -#include +#include #include #include +#include #include #include diff --git a/src/transport/tests/TestSecureSessionTable.cpp b/src/transport/tests/TestSecureSessionTable.cpp index 323558a0cecd24..da5ca96951c6ed 100644 --- a/src/transport/tests/TestSecureSessionTable.cpp +++ b/src/transport/tests/TestSecureSessionTable.cpp @@ -24,11 +24,12 @@ #include #include -#include +#include -#include "system/SystemClock.h" #include +#include #include +#include #include #include diff --git a/src/transport/tests/TestSessionManager.cpp b/src/transport/tests/TestSessionManager.cpp index c5384a7be40328..154071a56418c5 100644 --- a/src/transport/tests/TestSessionManager.cpp +++ b/src/transport/tests/TestSessionManager.cpp @@ -21,6 +21,10 @@ * This file implements unit tests for the SessionManager implementation. */ +#include + +#include + #define CHIP_ENABLE_TEST_ENCRYPTED_BUFFER_API // Up here in case some other header // includes SessionManager.h indirectly @@ -29,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -39,10 +44,6 @@ #include #include -#include - -#include - #undef CHIP_ENABLE_TEST_ENCRYPTED_BUFFER_API namespace { diff --git a/src/transport/tests/TestSessionManagerDispatch.cpp b/src/transport/tests/TestSessionManagerDispatch.cpp index f90cb0fa2b21ac..099ccec4b2f6c6 100644 --- a/src/transport/tests/TestSessionManagerDispatch.cpp +++ b/src/transport/tests/TestSessionManagerDispatch.cpp @@ -21,6 +21,10 @@ * This file implements unit tests for the SessionManager implementation. */ +#include + +#include + #define CHIP_ENABLE_TEST_ENCRYPTED_BUFFER_API // Up here in case some other header // includes SessionManager.h indirectly @@ -29,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -36,10 +41,6 @@ #include #include -#include - -#include - #undef CHIP_ENABLE_TEST_ENCRYPTED_BUFFER_API namespace { 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..a7fef6deeee4df 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 { @@ -15630,105 +16019,333 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value return emberAfWriteAttribute(endpoint, Clusters::EnergyPreference::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } -} // namespace CurrentLowPowerModeSensitivity +} // namespace CurrentLowPowerModeSensitivity + +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::EnergyPreference::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::EnergyPreference::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::EnergyPreference::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::EnergyPreference::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::EnergyPreference::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::EnergyPreference::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace EnergyPreference + +namespace PowerTopology { +namespace Attributes { + +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::PowerTopology::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::PowerTopology::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::PowerTopology::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace PowerTopology + +namespace EnergyEvseMode { +namespace Attributes { + +namespace StartUpMode { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (Traits::IsNullValue(temp)) + { + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); + } + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty) +{ + if (value.IsNull()) + { + return SetNull(endpoint, markDirty); + } + + return Set(endpoint, value.Value(), markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } + + return Set(endpoint, value.Value()); +} + +} // namespace StartUpMode -namespace FeatureMap { +namespace OnMode { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::EnergyPreference::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + if (Traits::IsNullValue(temp)) { - return Protocols::InteractionModel::Status::ConstraintError; + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); } - *value = Traits::StorageToWorking(temp); return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; } Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::EnergyPreference::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value) { - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; } Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::EnergyPreference::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } -} // namespace FeatureMap - -namespace ClusterRevision { +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); +} -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) { - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::EnergyPreference::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; + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + if (value.IsNull()) { - return Protocols::InteractionModel::Status::ConstraintError; + return SetNull(endpoint, markDirty); } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::EnergyPreference::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + + return Set(endpoint, value.Value(), markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) { - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + if (value.IsNull()) { - return Protocols::InteractionModel::Status::ConstraintError; + return SetNull(endpoint); } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::EnergyPreference::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); -} - -} // namespace ClusterRevision -} // namespace Attributes -} // namespace EnergyPreference + return Set(endpoint, value.Value()); +} -namespace PowerTopology { -namespace Attributes { +} // namespace OnMode namespace ClusterRevision { @@ -15738,7 +16355,7 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * va Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::PowerTopology::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -15758,7 +16375,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::PowerTopology::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) @@ -15771,15 +16388,15 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::PowerTopology::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } } // namespace ClusterRevision } // namespace Attributes -} // namespace PowerTopology +} // namespace EnergyEvseMode -namespace EnergyEvseMode { +namespace WaterHeaterMode { namespace Attributes { namespace StartUpMode { @@ -15790,7 +16407,7 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nu Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (Traits::IsNullValue(temp)) { @@ -15813,7 +16430,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value) @@ -15826,7 +16443,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) @@ -15835,7 +16452,7 @@ Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttri Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) @@ -15844,7 +16461,7 @@ Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, @@ -15878,7 +16495,7 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nu Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (Traits::IsNullValue(temp)) { @@ -15901,7 +16518,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value) @@ -15914,7 +16531,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) @@ -15923,7 +16540,7 @@ Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttri Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) @@ -15932,7 +16549,7 @@ Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, @@ -15966,7 +16583,7 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * va Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -15986,7 +16603,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) @@ -15999,13 +16616,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } } // namespace ClusterRevision } // namespace Attributes -} // namespace EnergyEvseMode +} // namespace WaterHeaterMode namespace DeviceEnergyManagementMode { namespace Attributes { @@ -38256,6 +38873,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..63493b3f90551d 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 { @@ -2633,6 +2700,40 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace Attributes } // namespace EnergyEvseMode +namespace WaterHeaterMode { +namespace Attributes { + +namespace StartUpMode { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int8u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty); +} // namespace StartUpMode + +namespace OnMode { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int8u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty); +} // namespace OnMode + +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 WaterHeaterMode + namespace DeviceEnergyManagementMode { namespace Attributes { @@ -5894,6 +5995,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..6e78fd6c09a8bf 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 */ @@ -403,6 +408,11 @@ void emberAfPowerTopologyClusterInitCallback(chip::EndpointId endpoint); */ void emberAfEnergyEvseModeClusterInitCallback(chip::EndpointId endpoint); +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfWaterHeaterModeClusterInitCallback(chip::EndpointId endpoint); + /** * @param endpoint Endpoint that is being initialized */ @@ -623,6 +633,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 +3245,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 // @@ -3501,6 +3554,45 @@ MatterEnergyEvseModeClusterServerPreAttributeChangedCallback(const chip::app::Co */ void emberAfEnergyEvseModeClusterServerTickCallback(chip::EndpointId endpoint); +// +// Water Heater Mode Cluster +// + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfWaterHeaterModeClusterServerInitCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being shutdown + */ +void MatterWaterHeaterModeClusterServerShutdownCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfWaterHeaterModeClusterClientInitCallback(chip::EndpointId endpoint); + +/** + * @param attributePath Concrete attribute path that changed + */ +void MatterWaterHeaterModeClusterServerAttributeChangedCallback(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 +MatterWaterHeaterModeClusterServerPreAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath, + EmberAfAttributeType attributeType, uint16_t size, uint8_t * value); + +/** + * @param endpoint Endpoint that is being served + */ +void emberAfWaterHeaterModeClusterServerTickCallback(chip::EndpointId endpoint); + // // Device Energy Management Mode Cluster // @@ -5206,6 +5298,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 +6010,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) */ @@ -5923,6 +6065,12 @@ bool emberAfMessagesClusterPresentMessagesRequestCallback( bool emberAfMessagesClusterCancelMessagesRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::Messages::Commands::CancelMessagesRequest::DecodableType & commandData); +/** + * @brief Water Heater Mode Cluster ChangeToMode Command callback (from client) + */ +bool emberAfWaterHeaterModeClusterChangeToModeCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::WaterHeaterMode::Commands::ChangeToMode::DecodableType & commandData); /** * @brief Door Lock Cluster LockDoor Command callback (from client) */ @@ -6630,6 +6778,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..13951c0ff2bc00 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; @@ -1881,6 +1895,20 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(EnergyPreference::Energ } } +static auto __attribute__((unused)) EnsureKnownEnumValue(WaterHeaterMode::ModeTag val) +{ + using EnumType = WaterHeaterMode::ModeTag; + switch (val) + { + case EnumType::kOff: + case EnumType::kManual: + case EnumType::kTimed: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} + static auto __attribute__((unused)) EnsureKnownEnumValue(DoorLock::AlarmCodeEnum val) { using EnumType = DoorLock::AlarmCodeEnum; 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..99b7167b26bee3 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 @@ -2765,6 +2808,28 @@ enum class Feature : uint32_t }; } // namespace EnergyEvseMode +namespace WaterHeaterMode { + +// Enum for ModeTag +enum class ModeTag : uint16_t +{ + kOff = 0x4000, + kManual = 0x4001, + kTimed = 0x4002, + // 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 = 0, +}; + +// Bitmap for Feature +enum class Feature : uint32_t +{ + kOnOff = 0x1, +}; +} // namespace WaterHeaterMode + namespace DeviceEnergyManagementMode { // Enum for ModeTag @@ -5133,6 +5198,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..fcae2110b2ce53 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 { } @@ -17369,6 +17501,119 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre namespace Events {} // namespace Events } // namespace EnergyEvseMode +namespace WaterHeaterMode { +namespace Structs {} // namespace Structs + +namespace Commands { +namespace ChangeToMode { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kNewMode), newMode); + 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::kNewMode)) + { + err = DataModel::Decode(reader, newMode); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace ChangeToMode. +namespace ChangeToModeResponse { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kStatus), status); + encoder.Encode(to_underlying(Fields::kStatusText), statusText); + 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::kStatus)) + { + err = DataModel::Decode(reader, status); + } + else if (__context_tag == to_underlying(Fields::kStatusText)) + { + err = DataModel::Decode(reader, statusText); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace ChangeToModeResponse. +} // namespace Commands + +namespace Attributes { +CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path) +{ + switch (path.mAttributeId) + { + case Attributes::SupportedModes::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, supportedModes); + case Attributes::CurrentMode::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, currentMode); + case Attributes::StartUpMode::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, startUpMode); + case Attributes::OnMode::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, onMode); + 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 WaterHeaterMode namespace DeviceEnergyManagementMode { namespace Structs {} // namespace Structs @@ -27815,6 +28060,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 +31902,13 @@ bool CommandIsFabricScoped(ClusterId aCluster, CommandId aCommand) return false; } } + case Clusters::WaterHeaterManagement::Id: { + switch (aCommand) + { + default: + return false; + } + } case Clusters::DemandResponseLoadControl::Id: { switch (aCommand) { @@ -31460,6 +31948,13 @@ bool CommandIsFabricScoped(ClusterId aCluster, CommandId aCommand) return false; } } + case Clusters::WaterHeaterMode::Id: { + switch (aCommand) + { + default: + return false; + } + } case Clusters::DeviceEnergyManagementMode::Id: { switch (aCommand) { @@ -31627,6 +32122,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..9377e6e1739a75 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); }; @@ -23846,61 +24085,261 @@ namespace Attributes { namespace AvailableEndpoints { struct TypeInfo { - using Type = chip::app::DataModel::List; - using DecodableType = chip::app::DataModel::DecodableList; - using DecodableArgType = const chip::app::DataModel::DecodableList &; + using Type = chip::app::DataModel::List; + using DecodableType = chip::app::DataModel::DecodableList; + using DecodableArgType = const chip::app::DataModel::DecodableList &; + + static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::AvailableEndpoints::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace AvailableEndpoints +namespace ActiveEndpoints { +struct TypeInfo +{ + using Type = chip::app::DataModel::List; + using DecodableType = chip::app::DataModel::DecodableList; + using DecodableArgType = const chip::app::DataModel::DecodableList &; + + static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::ActiveEndpoints::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace ActiveEndpoints +namespace GeneratedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } +}; +} // namespace GeneratedCommandList +namespace AcceptedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } +}; +} // namespace AcceptedCommandList +namespace EventList { +struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } +}; +} // namespace EventList +namespace AttributeList { +struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } +}; +} // namespace AttributeList +namespace FeatureMap { +struct TypeInfo : public Clusters::Globals::Attributes::FeatureMap::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } +}; +} // namespace FeatureMap +namespace ClusterRevision { +struct TypeInfo : public Clusters::Globals::Attributes::ClusterRevision::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } +}; +} // namespace ClusterRevision + +struct TypeInfo +{ + struct DecodableType + { + static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); + + Attributes::AvailableEndpoints::TypeInfo::DecodableType availableEndpoints; + Attributes::ActiveEndpoints::TypeInfo::DecodableType activeEndpoints; + 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 PowerTopology +namespace EnergyEvseMode { +namespace Structs { +namespace ModeTagStruct = Clusters::detail::Structs::ModeTagStruct; +namespace ModeOptionStruct = Clusters::detail::Structs::ModeOptionStruct; +} // namespace Structs + +namespace Commands { +// Forward-declarations so we can reference these later. + +namespace ChangeToMode { +struct Type; +struct DecodableType; +} // namespace ChangeToMode + +namespace ChangeToModeResponse { +struct Type; +struct DecodableType; +} // namespace ChangeToModeResponse + +} // namespace Commands + +namespace Commands { +namespace ChangeToMode { +enum class Fields : uint8_t +{ + kNewMode = 0, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::ChangeToMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + + uint8_t newMode = static_cast(0); + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::EnergyEvseMode::Commands::ChangeToModeResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::ChangeToMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + + uint8_t newMode = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace ChangeToMode +namespace ChangeToModeResponse { +enum class Fields : uint8_t +{ + kStatus = 0, + kStatusText = 1, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::ChangeToModeResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + + uint8_t status = static_cast(0); + Optional statusText; + + 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::ChangeToModeResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + + uint8_t status = static_cast(0); + Optional statusText; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace ChangeToModeResponse +} // namespace Commands + +namespace Attributes { + +namespace SupportedModes { +struct TypeInfo +{ + using Type = chip::app::DataModel::List; + using DecodableType = + chip::app::DataModel::DecodableList; + using DecodableArgType = + const chip::app::DataModel::DecodableList &; + + static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::SupportedModes::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace SupportedModes +namespace CurrentMode { +struct TypeInfo +{ + using Type = uint8_t; + using DecodableType = uint8_t; + using DecodableArgType = uint8_t; + + static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::CurrentMode::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace CurrentMode +namespace StartUpMode { +struct TypeInfo +{ + using Type = chip::app::DataModel::Nullable; + using DecodableType = chip::app::DataModel::Nullable; + using DecodableArgType = const chip::app::DataModel::Nullable &; - static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::AvailableEndpoints::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::StartUpMode::Id; } static constexpr bool MustUseTimedWrite() { return false; } }; -} // namespace AvailableEndpoints -namespace ActiveEndpoints { +} // namespace StartUpMode +namespace OnMode { struct TypeInfo { - using Type = chip::app::DataModel::List; - using DecodableType = chip::app::DataModel::DecodableList; - using DecodableArgType = const chip::app::DataModel::DecodableList &; + using Type = chip::app::DataModel::Nullable; + using DecodableType = chip::app::DataModel::Nullable; + using DecodableArgType = const chip::app::DataModel::Nullable &; - static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::ActiveEndpoints::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::OnMode::Id; } static constexpr bool MustUseTimedWrite() { return false; } }; -} // namespace ActiveEndpoints +} // namespace OnMode namespace GeneratedCommandList { struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo { - static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } }; } // namespace GeneratedCommandList namespace AcceptedCommandList { struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::TypeInfo { - static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } }; } // namespace AcceptedCommandList namespace EventList { struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo { - static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } }; } // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { - static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } }; } // namespace AttributeList namespace FeatureMap { struct TypeInfo : public Clusters::Globals::Attributes::FeatureMap::TypeInfo { - static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } }; } // namespace FeatureMap namespace ClusterRevision { struct TypeInfo : public Clusters::Globals::Attributes::ClusterRevision::TypeInfo { - static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } }; } // namespace ClusterRevision @@ -23908,12 +24347,14 @@ struct TypeInfo { struct DecodableType { - static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); - Attributes::AvailableEndpoints::TypeInfo::DecodableType availableEndpoints; - Attributes::ActiveEndpoints::TypeInfo::DecodableType activeEndpoints; + Attributes::SupportedModes::TypeInfo::DecodableType supportedModes; + Attributes::CurrentMode::TypeInfo::DecodableType currentMode = static_cast(0); + Attributes::StartUpMode::TypeInfo::DecodableType startUpMode; + Attributes::OnMode::TypeInfo::DecodableType onMode; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; Attributes::EventList::TypeInfo::DecodableType eventList; @@ -23923,8 +24364,8 @@ struct TypeInfo }; }; } // namespace Attributes -} // namespace PowerTopology -namespace EnergyEvseMode { +} // namespace EnergyEvseMode +namespace WaterHeaterMode { namespace Structs { namespace ModeTagStruct = Clusters::detail::Structs::ModeTagStruct; namespace ModeOptionStruct = Clusters::detail::Structs::ModeOptionStruct; @@ -23957,13 +24398,13 @@ struct Type public: // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand static constexpr CommandId GetCommandId() { return Commands::ChangeToMode::Id; } - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } uint8_t newMode = static_cast(0); CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; - using ResponseType = Clusters::EnergyEvseMode::Commands::ChangeToModeResponse::DecodableType; + using ResponseType = Clusters::WaterHeaterMode::Commands::ChangeToModeResponse::DecodableType; static constexpr bool MustUseTimedInvoke() { return false; } }; @@ -23972,7 +24413,7 @@ struct DecodableType { public: static constexpr CommandId GetCommandId() { return Commands::ChangeToMode::Id; } - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } uint8_t newMode = static_cast(0); CHIP_ERROR Decode(TLV::TLVReader & reader); @@ -23990,7 +24431,7 @@ struct Type public: // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand static constexpr CommandId GetCommandId() { return Commands::ChangeToModeResponse::Id; } - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } uint8_t status = static_cast(0); Optional statusText; @@ -24006,7 +24447,7 @@ struct DecodableType { public: static constexpr CommandId GetCommandId() { return Commands::ChangeToModeResponse::Id; } - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } uint8_t status = static_cast(0); Optional statusText; @@ -24020,13 +24461,13 @@ namespace Attributes { namespace SupportedModes { struct TypeInfo { - using Type = chip::app::DataModel::List; + using Type = chip::app::DataModel::List; using DecodableType = - chip::app::DataModel::DecodableList; + chip::app::DataModel::DecodableList; using DecodableArgType = - const chip::app::DataModel::DecodableList &; + const chip::app::DataModel::DecodableList &; - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } static constexpr AttributeId GetAttributeId() { return Attributes::SupportedModes::Id; } static constexpr bool MustUseTimedWrite() { return false; } }; @@ -24038,7 +24479,7 @@ struct TypeInfo using DecodableType = uint8_t; using DecodableArgType = uint8_t; - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } static constexpr AttributeId GetAttributeId() { return Attributes::CurrentMode::Id; } static constexpr bool MustUseTimedWrite() { return false; } }; @@ -24050,7 +24491,7 @@ struct TypeInfo using DecodableType = chip::app::DataModel::Nullable; using DecodableArgType = const chip::app::DataModel::Nullable &; - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } static constexpr AttributeId GetAttributeId() { return Attributes::StartUpMode::Id; } static constexpr bool MustUseTimedWrite() { return false; } }; @@ -24062,7 +24503,7 @@ struct TypeInfo using DecodableType = chip::app::DataModel::Nullable; using DecodableArgType = const chip::app::DataModel::Nullable &; - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } static constexpr AttributeId GetAttributeId() { return Attributes::OnMode::Id; } static constexpr bool MustUseTimedWrite() { return false; } }; @@ -24070,37 +24511,37 @@ struct TypeInfo namespace GeneratedCommandList { struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo { - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } }; } // namespace GeneratedCommandList namespace AcceptedCommandList { struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::TypeInfo { - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } }; } // namespace AcceptedCommandList namespace EventList { struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo { - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } }; } // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } }; } // namespace AttributeList namespace FeatureMap { struct TypeInfo : public Clusters::Globals::Attributes::FeatureMap::TypeInfo { - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } }; } // namespace FeatureMap namespace ClusterRevision { struct TypeInfo : public Clusters::Globals::Attributes::ClusterRevision::TypeInfo { - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } }; } // namespace ClusterRevision @@ -24108,7 +24549,7 @@ struct TypeInfo { struct DecodableType { - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); @@ -24125,7 +24566,7 @@ struct TypeInfo }; }; } // namespace Attributes -} // namespace EnergyEvseMode +} // namespace WaterHeaterMode namespace DeviceEnergyManagementMode { namespace Structs { namespace ModeTagStruct = Clusters::detail::Structs::ModeTagStruct; @@ -40750,6 +41191,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..c80ee5f834801e 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 { @@ -4219,6 +4273,52 @@ static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; } // namespace Attributes } // namespace EnergyEvseMode +namespace WaterHeaterMode { +namespace Attributes { + +namespace SupportedModes { +static constexpr AttributeId Id = 0x00000000; +} // namespace SupportedModes + +namespace CurrentMode { +static constexpr AttributeId Id = 0x00000001; +} // namespace CurrentMode + +namespace StartUpMode { +static constexpr AttributeId Id = 0x00000002; +} // namespace StartUpMode + +namespace OnMode { +static constexpr AttributeId Id = 0x00000003; +} // namespace OnMode + +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 WaterHeaterMode + namespace DeviceEnergyManagementMode { namespace Attributes { @@ -6699,7 +6799,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 +7459,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..b94e6c1772f2aa 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 @@ -247,6 +250,9 @@ static constexpr ClusterId Id = 0x0000009C; namespace EnergyEvseMode { static constexpr ClusterId Id = 0x0000009D; } // namespace EnergyEvseMode +namespace WaterHeaterMode { +static constexpr ClusterId Id = 0x0000009E; +} // namespace WaterHeaterMode namespace DeviceEnergyManagementMode { static constexpr ClusterId Id = 0x0000009F; } // namespace DeviceEnergyManagementMode @@ -379,6 +385,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..382737bcee0c8e 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 { @@ -1059,6 +1073,20 @@ static constexpr CommandId Id = 0x00000001; } // namespace Commands } // namespace EnergyEvseMode +namespace WaterHeaterMode { +namespace Commands { + +namespace ChangeToMode { +static constexpr CommandId Id = 0x00000000; +} // namespace ChangeToMode + +namespace ChangeToModeResponse { +static constexpr CommandId Id = 0x00000001; +} // namespace ChangeToModeResponse + +} // namespace Commands +} // namespace WaterHeaterMode + namespace DeviceEnergyManagementMode { namespace Commands { @@ -1429,15 +1457,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 +1797,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..c5971984fed334 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 | @@ -109,6 +110,7 @@ | EnergyPreference | 0x009B | | PowerTopology | 0x009C | | EnergyEvseMode | 0x009D | +| WaterHeaterMode | 0x009E | | DeviceEnergyManagementMode | 0x009F | | DoorLock | 0x0101 | | WindowCovering | 0x0102 | @@ -153,6 +155,7 @@ | AccountLogin | 0x050E | | ContentControl | 0x050F | | ContentAppObserver | 0x0510 | +| CommissionerControl | 0x0751 | | ElectricalMeasurement | 0x0B04 | | UnitTesting | 0xFFF1FC05| | FaultInjection | 0xFFF1FC06| @@ -6573,6 +6576,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 | |------------------------------------------------------------------------------| @@ -7681,6 +7787,64 @@ class EnergyEvseModeChangeToMode : public ClusterCommand chip::app::Clusters::EnergyEvseMode::Commands::ChangeToMode::Type mRequest; }; +/*----------------------------------------------------------------------------*\ +| Cluster WaterHeaterMode | 0x009E | +|------------------------------------------------------------------------------| +| Commands: | | +| * ChangeToMode | 0x00 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * SupportedModes | 0x0000 | +| * CurrentMode | 0x0001 | +| * StartUpMode | 0x0002 | +| * OnMode | 0x0003 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +/* + * Command ChangeToMode + */ +class WaterHeaterModeChangeToMode : public ClusterCommand +{ +public: + WaterHeaterModeChangeToMode(CredentialIssuerCommands * credsIssuerConfig) : ClusterCommand("change-to-mode", credsIssuerConfig) + { + AddArgument("NewMode", 0, UINT8_MAX, &mRequest.newMode); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WaterHeaterMode::Commands::ChangeToMode::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::WaterHeaterMode::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WaterHeaterMode::Commands::ChangeToMode::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::WaterHeaterMode::Commands::ChangeToMode::Type mRequest; +}; + /*----------------------------------------------------------------------------*\ | Cluster DeviceEnergyManagementMode | 0x009F | |------------------------------------------------------------------------------| @@ -11185,15 +11349,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 +13815,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 +21169,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; @@ -21573,6 +21917,75 @@ void registerClusterEnergyEvseMode(Commands & commands, CredentialIssuerCommands commands.RegisterCluster(clusterName, clusterCommands); } +void registerClusterWaterHeaterMode(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) +{ + using namespace chip::app::Clusters::WaterHeaterMode; + + const char * clusterName = "WaterHeaterMode"; + + commands_list clusterCommands = { + // + // Commands + // + make_unique(Id, credsIssuerConfig), // + make_unique(credsIssuerConfig), // + // + // Attributes + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "supported-modes", Attributes::SupportedModes::Id, credsIssuerConfig), // + make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // + make_unique(Id, "start-up-mode", Attributes::StartUpMode::Id, credsIssuerConfig), // + make_unique(Id, "on-mode", Attributes::OnMode::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-modes", Attributes::SupportedModes::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "current-mode", 0, UINT8_MAX, Attributes::CurrentMode::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "start-up-mode", 0, UINT8_MAX, Attributes::StartUpMode::Id, WriteCommandType::kWrite, credsIssuerConfig), // + make_unique>>(Id, "on-mode", 0, UINT8_MAX, Attributes::OnMode::Id, + WriteCommandType::kWrite, 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-modes", Attributes::SupportedModes::Id, credsIssuerConfig), // + make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // + make_unique(Id, "start-up-mode", Attributes::StartUpMode::Id, credsIssuerConfig), // + make_unique(Id, "on-mode", Attributes::OnMode::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 registerClusterDeviceEnergyManagementMode(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) { using namespace chip::app::Clusters::DeviceEnergyManagementMode; @@ -26289,6 +26702,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 +28122,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); @@ -27653,6 +28130,7 @@ void registerClusters(Commands & commands, CredentialIssuerCommands * credsIssue registerClusterEnergyPreference(commands, credsIssuerConfig); registerClusterPowerTopology(commands, credsIssuerConfig); registerClusterEnergyEvseMode(commands, credsIssuerConfig); + registerClusterWaterHeaterMode(commands, credsIssuerConfig); registerClusterDeviceEnergyManagementMode(commands, credsIssuerConfig); registerClusterDoorLock(commands, credsIssuerConfig); registerClusterWindowCovering(commands, credsIssuerConfig); @@ -27697,6 +28175,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..9de841aaaa4af3 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, "{"); @@ -7967,6 +8023,15 @@ 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 WaterHeaterMode::Commands::ChangeToModeResponse::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("status", indent + 1, value.status)); + ReturnErrorOnFailure(DataModelLogger::LogValue("statusText", indent + 1, value.statusText)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const DeviceEnergyManagementMode::Commands::ChangeToModeResponse::DecodableType & value) { @@ -8196,6 +8261,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 +13123,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) { @@ -13568,6 +13711,63 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP } break; } + case WaterHeaterMode::Id: { + switch (path.mAttributeId) + { + case WaterHeaterMode::Attributes::SupportedModes::Id: { + chip::app::DataModel::DecodableList + value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("SupportedModes", 1, value); + } + case WaterHeaterMode::Attributes::CurrentMode::Id: { + uint8_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("CurrentMode", 1, value); + } + case WaterHeaterMode::Attributes::StartUpMode::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("StartUpMode", 1, value); + } + case WaterHeaterMode::Attributes::OnMode::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("OnMode", 1, value); + } + case WaterHeaterMode::Attributes::GeneratedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("GeneratedCommandList", 1, value); + } + case WaterHeaterMode::Attributes::AcceptedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AcceptedCommandList", 1, value); + } + case WaterHeaterMode::Attributes::EventList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EventList", 1, value); + } + case WaterHeaterMode::Attributes::AttributeList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AttributeList", 1, value); + } + case WaterHeaterMode::Attributes::FeatureMap::Id: { + uint32_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("FeatureMap", 1, value); + } + case WaterHeaterMode::Attributes::ClusterRevision::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ClusterRevision", 1, value); + } + } + break; + } case DeviceEnergyManagementMode::Id: { switch (path.mAttributeId) { @@ -17444,6 +17644,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) { @@ -19012,6 +19253,17 @@ CHIP_ERROR DataModelLogger::LogCommand(const chip::app::ConcreteCommandPath & pa } break; } + case WaterHeaterMode::Id: { + switch (path.mCommandId) + { + case WaterHeaterMode::Commands::ChangeToModeResponse::Id: { + WaterHeaterMode::Commands::ChangeToModeResponse::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ChangeToModeResponse", 1, value); + } + } + break; + } case DeviceEnergyManagementMode::Id: { switch (path.mCommandId) { @@ -19223,6 +19475,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 +20373,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..8ca6e2ef3904d6 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, @@ -745,6 +748,8 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::EnergyEvse::Commands::GetTargetsResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::EnergyEvseMode::Commands::ChangeToModeResponse::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::WaterHeaterMode::Commands::ChangeToModeResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::DeviceEnergyManagementMode::Commands::ChangeToModeResponse::DecodableType & value); @@ -797,6 +802,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..c9386dc42a6a7b 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 | @@ -111,6 +112,7 @@ | EnergyPreference | 0x009B | | PowerTopology | 0x009C | | EnergyEvseMode | 0x009D | +| WaterHeaterMode | 0x009E | | DeviceEnergyManagementMode | 0x009F | | DoorLock | 0x0101 | | WindowCovering | 0x0102 | @@ -155,6 +157,7 @@ | AccountLogin | 0x050E | | ContentControl | 0x050F | | ContentAppObserver | 0x0510 | +| CommissionerControl | 0x0751 | | ElectricalMeasurement | 0x0B04 | | UnitTesting | 0xFFF1FC05| | FaultInjection | 0xFFF1FC06| @@ -78994,6 +78997,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 | @@ -89098,6 +90297,1027 @@ class SubscribeAttributeEnergyEvseModeClusterRevision : public SubscribeAttribut } }; +#endif // MTR_ENABLE_PROVISIONAL +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/*----------------------------------------------------------------------------*\ +| Cluster WaterHeaterMode | 0x009E | +|------------------------------------------------------------------------------| +| Commands: | | +| * ChangeToMode | 0x00 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * SupportedModes | 0x0000 | +| * CurrentMode | 0x0001 | +| * StartUpMode | 0x0002 | +| * OnMode | 0x0003 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +#if MTR_ENABLE_PROVISIONAL +/* + * Command ChangeToMode + */ +class WaterHeaterModeChangeToMode : public ClusterCommand { +public: + WaterHeaterModeChangeToMode() + : ClusterCommand("change-to-mode") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("NewMode", 0, UINT8_MAX, &mRequest.newMode); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WaterHeaterMode::Commands::ChangeToMode::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 = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWaterHeaterModeClusterChangeToModeParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.newMode = [NSNumber numberWithUnsignedChar:mRequest.newMode]; +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster changeToModeWithParams:params completion: + ^(MTRWaterHeaterModeClusterChangeToModeResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::WaterHeaterMode::Commands::ChangeToModeResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::WaterHeaterMode::Commands::ChangeToModeResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::WaterHeaterMode::Commands::ChangeToMode::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL + +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute SupportedModes + */ +class ReadWaterHeaterModeSupportedModes : public ReadAttribute { +public: + ReadWaterHeaterModeSupportedModes() + : ReadAttribute("supported-modes") + { + } + + ~ReadWaterHeaterModeSupportedModes() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::SupportedModes::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 = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeSupportedModesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.SupportedModes response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode SupportedModes read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeSupportedModes : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeSupportedModes() + : SubscribeAttribute("supported-modes") + { + } + + ~SubscribeAttributeWaterHeaterModeSupportedModes() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::SupportedModes::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 = [[MTRBaseClusterWaterHeaterMode 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 subscribeAttributeSupportedModesWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.SupportedModes 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 CurrentMode + */ +class ReadWaterHeaterModeCurrentMode : public ReadAttribute { +public: + ReadWaterHeaterModeCurrentMode() + : ReadAttribute("current-mode") + { + } + + ~ReadWaterHeaterModeCurrentMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::CurrentMode::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 = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeCurrentModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.CurrentMode response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode CurrentMode read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeCurrentMode : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeCurrentMode() + : SubscribeAttribute("current-mode") + { + } + + ~SubscribeAttributeWaterHeaterModeCurrentMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::CurrentMode::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 = [[MTRBaseClusterWaterHeaterMode 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 subscribeAttributeCurrentModeWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.CurrentMode 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 StartUpMode + */ +class ReadWaterHeaterModeStartUpMode : public ReadAttribute { +public: + ReadWaterHeaterModeStartUpMode() + : ReadAttribute("start-up-mode") + { + } + + ~ReadWaterHeaterModeStartUpMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::StartUpMode::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 = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeStartUpModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.StartUpMode response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode StartUpMode read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteWaterHeaterModeStartUpMode : public WriteAttribute { +public: + WriteWaterHeaterModeStartUpMode() + : WriteAttribute("start-up-mode") + { + AddArgument("attr-name", "start-up-mode"); + AddArgument("attr-value", 0, UINT8_MAX, &mValue); + WriteAttribute::AddArguments(); + } + + ~WriteWaterHeaterModeStartUpMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::StartUpMode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (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 = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWriteParams alloc] init]; + params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; + NSNumber * _Nullable value = nil; + if (!mValue.IsNull()) { + value = [NSNumber numberWithUnsignedChar:mValue.Value()]; + } + + [cluster writeAttributeStartUpModeWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("WaterHeaterMode StartUpMode write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + chip::app::DataModel::Nullable mValue; +}; + +class SubscribeAttributeWaterHeaterModeStartUpMode : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeStartUpMode() + : SubscribeAttribute("start-up-mode") + { + } + + ~SubscribeAttributeWaterHeaterModeStartUpMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::StartUpMode::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 = [[MTRBaseClusterWaterHeaterMode 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 subscribeAttributeStartUpModeWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.StartUpMode 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 OnMode + */ +class ReadWaterHeaterModeOnMode : public ReadAttribute { +public: + ReadWaterHeaterModeOnMode() + : ReadAttribute("on-mode") + { + } + + ~ReadWaterHeaterModeOnMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::OnMode::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 = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeOnModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.OnMode response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode OnMode read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteWaterHeaterModeOnMode : public WriteAttribute { +public: + WriteWaterHeaterModeOnMode() + : WriteAttribute("on-mode") + { + AddArgument("attr-name", "on-mode"); + AddArgument("attr-value", 0, UINT8_MAX, &mValue); + WriteAttribute::AddArguments(); + } + + ~WriteWaterHeaterModeOnMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::OnMode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (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 = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWriteParams alloc] init]; + params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; + NSNumber * _Nullable value = nil; + if (!mValue.IsNull()) { + value = [NSNumber numberWithUnsignedChar:mValue.Value()]; + } + + [cluster writeAttributeOnModeWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("WaterHeaterMode OnMode write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + chip::app::DataModel::Nullable mValue; +}; + +class SubscribeAttributeWaterHeaterModeOnMode : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeOnMode() + : SubscribeAttribute("on-mode") + { + } + + ~SubscribeAttributeWaterHeaterModeOnMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::OnMode::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 = [[MTRBaseClusterWaterHeaterMode 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 subscribeAttributeOnModeWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.OnMode 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 ReadWaterHeaterModeGeneratedCommandList : public ReadAttribute { +public: + ReadWaterHeaterModeGeneratedCommandList() + : ReadAttribute("generated-command-list") + { + } + + ~ReadWaterHeaterModeGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::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 = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode GeneratedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeGeneratedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeGeneratedCommandList() + : SubscribeAttribute("generated-command-list") + { + } + + ~SubscribeAttributeWaterHeaterModeGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::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 = [[MTRBaseClusterWaterHeaterMode 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(@"WaterHeaterMode.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 ReadWaterHeaterModeAcceptedCommandList : public ReadAttribute { +public: + ReadWaterHeaterModeAcceptedCommandList() + : ReadAttribute("accepted-command-list") + { + } + + ~ReadWaterHeaterModeAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::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 = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode AcceptedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeAcceptedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeAcceptedCommandList() + : SubscribeAttribute("accepted-command-list") + { + } + + ~SubscribeAttributeWaterHeaterModeAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::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 = [[MTRBaseClusterWaterHeaterMode 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(@"WaterHeaterMode.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 ReadWaterHeaterModeEventList : public ReadAttribute { +public: + ReadWaterHeaterModeEventList() + : ReadAttribute("event-list") + { + } + + ~ReadWaterHeaterModeEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::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 = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode EventList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeEventList : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeEventList() + : SubscribeAttribute("event-list") + { + } + + ~SubscribeAttributeWaterHeaterModeEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::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 = [[MTRBaseClusterWaterHeaterMode 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(@"WaterHeaterMode.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 ReadWaterHeaterModeAttributeList : public ReadAttribute { +public: + ReadWaterHeaterModeAttributeList() + : ReadAttribute("attribute-list") + { + } + + ~ReadWaterHeaterModeAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::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 = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode AttributeList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeAttributeList : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeAttributeList() + : SubscribeAttribute("attribute-list") + { + } + + ~SubscribeAttributeWaterHeaterModeAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::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 = [[MTRBaseClusterWaterHeaterMode 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(@"WaterHeaterMode.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 ReadWaterHeaterModeFeatureMap : public ReadAttribute { +public: + ReadWaterHeaterModeFeatureMap() + : ReadAttribute("feature-map") + { + } + + ~ReadWaterHeaterModeFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::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 = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode FeatureMap read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeFeatureMap : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeFeatureMap() + : SubscribeAttribute("feature-map") + { + } + + ~SubscribeAttributeWaterHeaterModeFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::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 = [[MTRBaseClusterWaterHeaterMode 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(@"WaterHeaterMode.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 ReadWaterHeaterModeClusterRevision : public ReadAttribute { +public: + ReadWaterHeaterModeClusterRevision() + : ReadAttribute("cluster-revision") + { + } + + ~ReadWaterHeaterModeClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::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 = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode ClusterRevision read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeClusterRevision : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeClusterRevision() + : SubscribeAttribute("cluster-revision") + { + } + + ~SubscribeAttributeWaterHeaterModeClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::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 = [[MTRBaseClusterWaterHeaterMode 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(@"WaterHeaterMode.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 @@ -145154,15 +147374,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 +163299,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 +192857,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 @@ -190440,6 +193509,68 @@ void registerClusterEnergyEvseMode(Commands & commands) commands.RegisterCluster(clusterName, clusterCommands); #endif // MTR_ENABLE_PROVISIONAL } +void registerClusterWaterHeaterMode(Commands & commands) +{ +#if MTR_ENABLE_PROVISIONAL + using namespace chip::app::Clusters::WaterHeaterMode; + + const char * clusterName = "WaterHeaterMode"; + + commands_list clusterCommands = { + make_unique(Id), // +#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(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + 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 registerClusterDeviceEnergyManagementMode(Commands & commands) { #if MTR_ENABLE_PROVISIONAL @@ -193137,6 +196268,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 +197071,7 @@ void registerClusters(Commands & commands) registerClusterValveConfigurationAndControl(commands); registerClusterElectricalPowerMeasurement(commands); registerClusterElectricalEnergyMeasurement(commands); + registerClusterWaterHeaterManagement(commands); registerClusterDemandResponseLoadControl(commands); registerClusterMessages(commands); registerClusterDeviceEnergyManagement(commands); @@ -193894,6 +197079,7 @@ void registerClusters(Commands & commands) registerClusterEnergyPreference(commands); registerClusterPowerTopology(commands); registerClusterEnergyEvseMode(commands); + registerClusterWaterHeaterMode(commands); registerClusterDeviceEnergyManagementMode(commands); registerClusterDoorLock(commands); registerClusterWindowCovering(commands); @@ -193938,6 +197124,7 @@ void registerClusters(Commands & commands) registerClusterAccountLogin(commands); registerClusterContentControl(commands); registerClusterContentAppObserver(commands); + registerClusterCommissionerControl(commands); registerClusterElectricalMeasurement(commands); registerClusterUnitTesting(commands); registerClusterSampleMei(commands);